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.
Files changed (348) hide show
  1. package/README.md +114 -48
  2. package/dist/ajv-patch.js +34 -0
  3. package/dist/cache/CacheInvalidation.d.ts +3 -1
  4. package/dist/cache/CacheInvalidation.d.ts.map +1 -1
  5. package/dist/cache/CacheInvalidation.js +10 -4
  6. package/dist/cache/CacheInvalidation.js.map +1 -1
  7. package/dist/cache/CacheManager.d.ts +3 -2
  8. package/dist/cache/CacheManager.d.ts.map +1 -1
  9. package/dist/cache/CacheManager.js +11 -3
  10. package/dist/cache/CacheManager.js.map +1 -1
  11. package/dist/cache/HttpCacheWrapper.d.ts +7 -6
  12. package/dist/cache/HttpCacheWrapper.d.ts.map +1 -1
  13. package/dist/cache/HttpCacheWrapper.js +8 -5
  14. package/dist/cache/HttpCacheWrapper.js.map +1 -1
  15. package/dist/cache/__tests__/HttpCacheWrapper.test.js +6 -5
  16. package/dist/cache/__tests__/HttpCacheWrapper.test.js.map +1 -1
  17. package/dist/cache/index.d.ts +3 -3
  18. package/dist/cache/index.d.ts.map +1 -1
  19. package/dist/cache/index.js +1 -1
  20. package/dist/cache/index.js.map +1 -1
  21. package/dist/client/CachedWordPressClient.d.ts +23 -9
  22. package/dist/client/CachedWordPressClient.d.ts.map +1 -1
  23. package/dist/client/CachedWordPressClient.js +4 -1
  24. package/dist/client/CachedWordPressClient.js.map +1 -1
  25. package/dist/client/MockWordPressClient.d.ts +2 -1
  26. package/dist/client/MockWordPressClient.d.ts.map +1 -1
  27. package/dist/client/MockWordPressClient.js +3 -1
  28. package/dist/client/MockWordPressClient.js.map +1 -1
  29. package/dist/client/api.d.ts +17 -13
  30. package/dist/client/api.d.ts.map +1 -1
  31. package/dist/client/api.js +135 -30
  32. package/dist/client/api.js.map +1 -1
  33. package/dist/client/auth.d.ts.map +1 -1
  34. package/dist/client/auth.js +2 -3
  35. package/dist/client/auth.js.map +1 -1
  36. package/dist/client/managers/AuthenticationManager.d.ts +55 -2
  37. package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
  38. package/dist/client/managers/AuthenticationManager.js +269 -71
  39. package/dist/client/managers/AuthenticationManager.js.map +1 -1
  40. package/dist/client/managers/BaseManager.d.ts +3 -3
  41. package/dist/client/managers/BaseManager.d.ts.map +1 -1
  42. package/dist/client/managers/BaseManager.js +11 -5
  43. package/dist/client/managers/BaseManager.js.map +1 -1
  44. package/dist/client/managers/RequestManager.d.ts +2 -2
  45. package/dist/client/managers/RequestManager.d.ts.map +1 -1
  46. package/dist/client/managers/RequestManager.js +25 -12
  47. package/dist/client/managers/RequestManager.js.map +1 -1
  48. package/dist/config/Config.d.ts +155 -0
  49. package/dist/config/Config.d.ts.map +1 -0
  50. package/dist/config/Config.js +215 -0
  51. package/dist/config/Config.js.map +1 -0
  52. package/dist/config/ConfigurationSchema.d.ts +21 -21
  53. package/dist/config/ConfigurationSchema.d.ts.map +1 -1
  54. package/dist/config/ConfigurationSchema.js +19 -2
  55. package/dist/config/ConfigurationSchema.js.map +1 -1
  56. package/dist/config/ServerConfiguration.d.ts +2 -1
  57. package/dist/config/ServerConfiguration.d.ts.map +1 -1
  58. package/dist/config/ServerConfiguration.js +50 -41
  59. package/dist/config/ServerConfiguration.js.map +1 -1
  60. package/dist/docs/DocumentationGenerator.d.ts +9 -8
  61. package/dist/docs/DocumentationGenerator.d.ts.map +1 -1
  62. package/dist/docs/DocumentationGenerator.js +10 -7
  63. package/dist/docs/DocumentationGenerator.js.map +1 -1
  64. package/dist/docs/MarkdownFormatter.d.ts.map +1 -1
  65. package/dist/docs/MarkdownFormatter.js +3 -2
  66. package/dist/docs/MarkdownFormatter.js.map +1 -1
  67. package/dist/dxt-entry.cjs +81 -0
  68. package/dist/dxt-entry.js +15 -14
  69. package/dist/dxt-entry.js.map +1 -1
  70. package/dist/index.d.ts +3 -1
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +37 -21
  73. package/dist/index.js.map +1 -1
  74. package/dist/performance/MetricsCollector.d.ts +13 -7
  75. package/dist/performance/MetricsCollector.d.ts.map +1 -1
  76. package/dist/performance/MetricsCollector.js +69 -27
  77. package/dist/performance/MetricsCollector.js.map +1 -1
  78. package/dist/performance/PerformanceAnalytics.d.ts +8 -2
  79. package/dist/performance/PerformanceAnalytics.d.ts.map +1 -1
  80. package/dist/performance/PerformanceAnalytics.js +17 -47
  81. package/dist/performance/PerformanceAnalytics.js.map +1 -1
  82. package/dist/performance/PerformanceMonitor.d.ts +2 -1
  83. package/dist/performance/PerformanceMonitor.d.ts.map +1 -1
  84. package/dist/performance/PerformanceMonitor.js +12 -13
  85. package/dist/performance/PerformanceMonitor.js.map +1 -1
  86. package/dist/performance/index.d.ts +2 -2
  87. package/dist/performance/index.d.ts.map +1 -1
  88. package/dist/security/AISecurityScanner.d.ts +1 -0
  89. package/dist/security/AISecurityScanner.d.ts.map +1 -1
  90. package/dist/security/AISecurityScanner.js +22 -12
  91. package/dist/security/AISecurityScanner.js.map +1 -1
  92. package/dist/security/AutomatedRemediation.d.ts +4 -3
  93. package/dist/security/AutomatedRemediation.d.ts.map +1 -1
  94. package/dist/security/AutomatedRemediation.js +46 -15
  95. package/dist/security/AutomatedRemediation.js.map +1 -1
  96. package/dist/security/InputValidator.d.ts +13 -9
  97. package/dist/security/InputValidator.d.ts.map +1 -1
  98. package/dist/security/InputValidator.js +4 -2
  99. package/dist/security/InputValidator.js.map +1 -1
  100. package/dist/security/SecurityCIPipeline.d.ts +1 -1
  101. package/dist/security/SecurityCIPipeline.d.ts.map +1 -1
  102. package/dist/security/SecurityCIPipeline.js +38 -29
  103. package/dist/security/SecurityCIPipeline.js.map +1 -1
  104. package/dist/security/SecurityConfig.d.ts +3 -3
  105. package/dist/security/SecurityConfig.d.ts.map +1 -1
  106. package/dist/security/SecurityConfig.js +13 -9
  107. package/dist/security/SecurityConfig.js.map +1 -1
  108. package/dist/security/SecurityConfigManager.d.ts +2 -2
  109. package/dist/security/SecurityConfigManager.d.ts.map +1 -1
  110. package/dist/security/SecurityConfigManager.js +20 -15
  111. package/dist/security/SecurityConfigManager.js.map +1 -1
  112. package/dist/security/SecurityMonitoring.d.ts +2 -2
  113. package/dist/security/SecurityMonitoring.d.ts.map +1 -1
  114. package/dist/security/SecurityMonitoring.js +19 -17
  115. package/dist/security/SecurityMonitoring.js.map +1 -1
  116. package/dist/security/SecurityReviewer.d.ts.map +1 -1
  117. package/dist/security/SecurityReviewer.js +10 -7
  118. package/dist/security/SecurityReviewer.js.map +1 -1
  119. package/dist/security/index.d.ts +24 -23
  120. package/dist/security/index.d.ts.map +1 -1
  121. package/dist/security/index.js +52 -23
  122. package/dist/security/index.js.map +1 -1
  123. package/dist/server/ConnectionTester.d.ts +12 -4
  124. package/dist/server/ConnectionTester.d.ts.map +1 -1
  125. package/dist/server/ConnectionTester.js +96 -22
  126. package/dist/server/ConnectionTester.js.map +1 -1
  127. package/dist/server/ToolRegistry.d.ts +2 -2
  128. package/dist/server/ToolRegistry.d.ts.map +1 -1
  129. package/dist/server/ToolRegistry.js +10 -5
  130. package/dist/server/ToolRegistry.js.map +1 -1
  131. package/dist/tools/BaseToolManager.d.ts +47 -11
  132. package/dist/tools/BaseToolManager.d.ts.map +1 -1
  133. package/dist/tools/BaseToolManager.js +168 -29
  134. package/dist/tools/BaseToolManager.js.map +1 -1
  135. package/dist/tools/auth.d.ts +16 -10
  136. package/dist/tools/auth.d.ts.map +1 -1
  137. package/dist/tools/auth.js +3 -2
  138. package/dist/tools/auth.js.map +1 -1
  139. package/dist/tools/cache.d.ts +30 -30
  140. package/dist/tools/cache.d.ts.map +1 -1
  141. package/dist/tools/cache.js +1 -6
  142. package/dist/tools/cache.js.map +1 -1
  143. package/dist/tools/comments.d.ts +20 -20
  144. package/dist/tools/comments.d.ts.map +1 -1
  145. package/dist/tools/comments.js +16 -9
  146. package/dist/tools/comments.js.map +1 -1
  147. package/dist/tools/media.d.ts +18 -16
  148. package/dist/tools/media.d.ts.map +1 -1
  149. package/dist/tools/media.js +16 -15
  150. package/dist/tools/media.js.map +1 -1
  151. package/dist/tools/pages.d.ts +19 -17
  152. package/dist/tools/pages.d.ts.map +1 -1
  153. package/dist/tools/pages.js +16 -12
  154. package/dist/tools/pages.js.map +1 -1
  155. package/dist/tools/performance.d.ts +11 -1
  156. package/dist/tools/performance.d.ts.map +1 -1
  157. package/dist/tools/performance.js +67 -34
  158. package/dist/tools/performance.js.map +1 -1
  159. package/dist/tools/posts/PostHandlers.d.ts +46 -0
  160. package/dist/tools/posts/PostHandlers.d.ts.map +1 -0
  161. package/dist/tools/posts/PostHandlers.js +400 -0
  162. package/dist/tools/posts/PostHandlers.js.map +1 -0
  163. package/dist/tools/posts/PostToolDefinitions.d.ts +37 -0
  164. package/dist/tools/posts/PostToolDefinitions.d.ts.map +1 -0
  165. package/dist/tools/posts/PostToolDefinitions.js +236 -0
  166. package/dist/tools/posts/PostToolDefinitions.js.map +1 -0
  167. package/dist/tools/posts/index.d.ts +138 -0
  168. package/dist/tools/posts/index.d.ts.map +1 -0
  169. package/dist/tools/posts/index.js +163 -0
  170. package/dist/tools/posts/index.js.map +1 -0
  171. package/dist/tools/posts.d.ts +10 -246
  172. package/dist/tools/posts.d.ts.map +1 -1
  173. package/dist/tools/posts.js +11 -723
  174. package/dist/tools/posts.js.map +1 -1
  175. package/dist/tools/site.d.ts +19 -18
  176. package/dist/tools/site.d.ts.map +1 -1
  177. package/dist/tools/site.js +14 -10
  178. package/dist/tools/site.js.map +1 -1
  179. package/dist/tools/taxonomies.d.ts +23 -24
  180. package/dist/tools/taxonomies.d.ts.map +1 -1
  181. package/dist/tools/taxonomies.js +24 -18
  182. package/dist/tools/taxonomies.js.map +1 -1
  183. package/dist/tools/users.d.ts +20 -15
  184. package/dist/tools/users.d.ts.map +1 -1
  185. package/dist/tools/users.js +12 -8
  186. package/dist/tools/users.js.map +1 -1
  187. package/dist/types/client.d.ts +48 -41
  188. package/dist/types/client.d.ts.map +1 -1
  189. package/dist/types/client.js +30 -5
  190. package/dist/types/client.js.map +1 -1
  191. package/dist/types/enhanced.d.ts +237 -0
  192. package/dist/types/enhanced.d.ts.map +1 -0
  193. package/dist/types/enhanced.js +49 -0
  194. package/dist/types/enhanced.js.map +1 -0
  195. package/dist/types/index.d.ts +15 -12
  196. package/dist/types/index.d.ts.map +1 -1
  197. package/dist/types/index.js +2 -0
  198. package/dist/types/index.js.map +1 -1
  199. package/dist/types/mcp.d.ts +12 -12
  200. package/dist/types/mcp.d.ts.map +1 -1
  201. package/dist/types/requests.d.ts +322 -0
  202. package/dist/types/requests.d.ts.map +1 -0
  203. package/dist/types/requests.js +8 -0
  204. package/dist/types/requests.js.map +1 -0
  205. package/dist/types/tools.d.ts +506 -0
  206. package/dist/types/tools.d.ts.map +1 -0
  207. package/dist/types/tools.js +8 -0
  208. package/dist/types/tools.js.map +1 -0
  209. package/dist/types/wordpress.d.ts +43 -15
  210. package/dist/types/wordpress.d.ts.map +1 -1
  211. package/dist/types/wordpress.js +8 -1
  212. package/dist/types/wordpress.js.map +1 -1
  213. package/dist/utils/debug.d.ts +19 -11
  214. package/dist/utils/debug.d.ts.map +1 -1
  215. package/dist/utils/debug.js +46 -10
  216. package/dist/utils/debug.js.map +1 -1
  217. package/dist/utils/enhancedError.d.ts +8 -8
  218. package/dist/utils/enhancedError.d.ts.map +1 -1
  219. package/dist/utils/enhancedError.js.map +1 -1
  220. package/dist/utils/error.d.ts +2 -4
  221. package/dist/utils/error.d.ts.map +1 -1
  222. package/dist/utils/error.js +42 -5
  223. package/dist/utils/error.js.map +1 -1
  224. package/dist/utils/logger.d.ts +106 -0
  225. package/dist/utils/logger.d.ts.map +1 -0
  226. package/dist/utils/logger.js +280 -0
  227. package/dist/utils/logger.js.map +1 -0
  228. package/dist/utils/streaming.d.ts +9 -9
  229. package/dist/utils/streaming.d.ts.map +1 -1
  230. package/dist/utils/streaming.js +71 -52
  231. package/dist/utils/streaming.js.map +1 -1
  232. package/dist/utils/toolWrapper.d.ts +9 -7
  233. package/dist/utils/toolWrapper.d.ts.map +1 -1
  234. package/dist/utils/toolWrapper.js.map +1 -1
  235. package/dist/utils/validation/core.d.ts +21 -0
  236. package/dist/utils/validation/core.d.ts.map +1 -0
  237. package/dist/utils/validation/core.js +71 -0
  238. package/dist/utils/validation/core.js.map +1 -0
  239. package/dist/utils/validation/index.d.ts +25 -0
  240. package/dist/utils/validation/index.d.ts.map +1 -0
  241. package/dist/utils/validation/index.js +29 -0
  242. package/dist/utils/validation/index.js.map +1 -0
  243. package/dist/utils/validation/network.d.ts +19 -0
  244. package/dist/utils/validation/network.d.ts.map +1 -0
  245. package/dist/utils/validation/network.js +93 -0
  246. package/dist/utils/validation/network.js.map +1 -0
  247. package/dist/utils/validation/rateLimit.d.ts +21 -0
  248. package/dist/utils/validation/rateLimit.d.ts.map +1 -0
  249. package/dist/utils/validation/rateLimit.js +43 -0
  250. package/dist/utils/validation/rateLimit.js.map +1 -0
  251. package/dist/utils/validation/security.d.ts +29 -0
  252. package/dist/utils/validation/security.d.ts.map +1 -0
  253. package/dist/utils/validation/security.js +327 -0
  254. package/dist/utils/validation/security.js.map +1 -0
  255. package/dist/utils/validation/wordpress.d.ts +31 -0
  256. package/dist/utils/validation/wordpress.d.ts.map +1 -0
  257. package/dist/utils/validation/wordpress.js +146 -0
  258. package/dist/utils/validation/wordpress.js.map +1 -0
  259. package/dist/utils/validation.d.ts +13 -82
  260. package/dist/utils/validation.d.ts.map +1 -1
  261. package/dist/utils/validation.js +25 -343
  262. package/dist/utils/validation.js.map +1 -1
  263. package/docs/BADGE_UPDATES.md +132 -0
  264. package/docs/CI_CD_IMPROVEMENTS.md +191 -0
  265. package/docs/INCREMENTAL_COVERAGE.md +183 -0
  266. package/docs/api/README.md +3 -1
  267. package/docs/api/openapi.json +5 -1
  268. package/docs/api/summary.json +1 -1
  269. package/docs/api/tools/wp_create_post.md +12 -14
  270. package/docs/examples/claude-desktop-config.md +1 -1
  271. package/docs/examples/docker-production.md +100 -93
  272. package/docs/examples/multi-site-setup.md +5 -4
  273. package/docs/examples/single-site-setup.md +3 -4
  274. package/docs/examples/use-case-workflows.md +4 -5
  275. package/docs/integrations/claude-desktop.md +31 -31
  276. package/docs/integrations/cline.md +4 -4
  277. package/docs/integrations/vs-code.md +9 -8
  278. package/docs/user-guides/SMITHERY_SETUP.md +10 -10
  279. package/package.json +44 -25
  280. package/src/cache/CacheInvalidation.ts +12 -5
  281. package/src/cache/CacheManager.ts +18 -15
  282. package/src/cache/HttpCacheWrapper.ts +30 -59
  283. package/src/cache/__tests__/HttpCacheWrapper.test.ts +6 -5
  284. package/src/cache/index.ts +3 -14
  285. package/src/client/CachedWordPressClient.ts +32 -30
  286. package/src/client/MockWordPressClient.ts +4 -2
  287. package/src/client/api.ts +186 -64
  288. package/src/client/auth.ts +15 -40
  289. package/src/client/managers/AuthenticationManager.ts +337 -77
  290. package/src/client/managers/BaseManager.ts +18 -30
  291. package/src/client/managers/RequestManager.ts +39 -44
  292. package/src/config/Config.ts +308 -0
  293. package/src/config/ConfigurationSchema.ts +23 -2
  294. package/src/config/ServerConfiguration.ts +51 -47
  295. package/src/docs/DocumentationGenerator.ts +50 -39
  296. package/src/docs/MarkdownFormatter.ts +19 -29
  297. package/src/dxt-entry.cjs +26 -16
  298. package/src/dxt-entry.ts +17 -27
  299. package/src/index.ts +42 -28
  300. package/src/performance/MetricsCollector.ts +108 -86
  301. package/src/performance/PerformanceAnalytics.ts +69 -164
  302. package/src/performance/PerformanceMonitor.ts +32 -47
  303. package/src/performance/index.ts +2 -10
  304. package/src/security/AISecurityScanner.ts +22 -12
  305. package/src/security/AutomatedRemediation.ts +49 -18
  306. package/src/security/InputValidator.ts +9 -6
  307. package/src/security/SecurityCIPipeline.ts +53 -37
  308. package/src/security/SecurityConfig.ts +22 -22
  309. package/src/security/SecurityConfigManager.ts +23 -19
  310. package/src/security/SecurityMonitoring.ts +24 -21
  311. package/src/security/SecurityReviewer.ts +10 -7
  312. package/src/security/index.ts +64 -29
  313. package/src/server/ConnectionTester.ts +120 -31
  314. package/src/server/ToolRegistry.ts +31 -21
  315. package/src/tools/BaseToolManager.ts +286 -33
  316. package/src/tools/auth.ts +20 -8
  317. package/src/tools/cache.ts +5 -15
  318. package/src/tools/comments.ts +34 -48
  319. package/src/tools/media.ts +41 -53
  320. package/src/tools/pages.ts +32 -54
  321. package/src/tools/performance.ts +141 -176
  322. package/src/tools/posts/PostHandlers.ts +474 -0
  323. package/src/tools/posts/PostToolDefinitions.ts +250 -0
  324. package/src/tools/posts/index.ts +192 -0
  325. package/src/tools/posts.ts +24 -780
  326. package/src/tools/site.ts +34 -19
  327. package/src/tools/taxonomies.ts +41 -57
  328. package/src/tools/users.ts +28 -16
  329. package/src/types/client.ts +114 -138
  330. package/src/types/enhanced.ts +318 -0
  331. package/src/types/index.ts +51 -30
  332. package/src/types/mcp.ts +20 -42
  333. package/src/types/requests.ts +378 -0
  334. package/src/types/tools.ts +608 -0
  335. package/src/types/wordpress.ts +56 -34
  336. package/src/utils/debug.ts +77 -59
  337. package/src/utils/enhancedError.ts +8 -8
  338. package/src/utils/error.ts +53 -31
  339. package/src/utils/logger.ts +351 -0
  340. package/src/utils/streaming.ts +86 -68
  341. package/src/utils/toolWrapper.ts +10 -12
  342. package/src/utils/validation/core.ts +108 -0
  343. package/src/utils/validation/index.ts +36 -0
  344. package/src/utils/validation/network.ts +132 -0
  345. package/src/utils/validation/rateLimit.ts +54 -0
  346. package/src/utils/validation/security.ts +361 -0
  347. package/src/utils/validation/wordpress.ts +180 -0
  348. package/src/utils/validation.ts +47 -470
@@ -1,84 +1,15 @@
1
1
  /**
2
- * Security-focused validation utilities for MCP WordPress
3
- */
4
- /**
5
- * Validates and sanitizes numeric IDs with comprehensive edge case handling
6
- */
7
- export declare function validateId(id: any, fieldName?: string): number;
8
- /**
9
- * Validates string length within bounds
10
- */
11
- export declare function validateString(value: any, fieldName: string, minLength?: number, maxLength?: number): string;
12
- /**
13
- * Validates and sanitizes file paths to prevent directory traversal
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":"AAGA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,SAAS,GAAE,MAAa,GAAG,MAAM,CA6CpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAE,MAAU,EAAE,SAAS,GAAE,MAAa,GAAG,MAAM,CAerH;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAWlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMzD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,GAAE,MAAc,GAAG,MAAM,CAgE1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,GAAE,MAAW,GAAG,IAAI,CAKpF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAQ/E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcjD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,EAAE,QAAQ,GAAE,MAAY,GAAG,CAAC,EAAE,CAcjH;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAsCzD;AAED;;;GAGG;AACH,cAAM,WAAW;IAIb,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ;IAJlB,OAAO,CAAC,QAAQ,CAAgE;gBAGtE,WAAW,GAAE,MAAU,EACvB,QAAQ,GAAE,MAAc;IAGlC,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAwB/B,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;CAGhC;AAGD,eAAO,MAAM,eAAe,aAA6B,CAAC;AAE1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBzD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,EAAE,GAAG,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAE,GAAG;IAC9F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAiDA;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAsDnD"}
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"}
@@ -1,345 +1,27 @@
1
- import * as path from "path";
2
- import { WordPressAPIError } from "../types/client.js";
3
1
  /**
4
- * Security-focused validation utilities for MCP WordPress
5
- */
6
- /**
7
- * Validates and sanitizes numeric IDs with comprehensive edge case handling
8
- */
9
- export function validateId(id, fieldName = "id") {
10
- // Handle null/undefined
11
- if (id === null || id === undefined) {
12
- throw new WordPressAPIError(`${fieldName} is required`, 400, "MISSING_PARAMETER");
13
- }
14
- // Convert to string first to handle various input types
15
- const strId = String(id).trim();
16
- // Check for empty string after trim
17
- if (strId === "") {
18
- throw new WordPressAPIError(`${fieldName} cannot be empty`, 400, "INVALID_PARAMETER");
19
- }
20
- // Handle decimal inputs
21
- if (strId.includes(".")) {
22
- throw new WordPressAPIError(`${fieldName} must be a whole number, not a decimal`, 400, "INVALID_PARAMETER");
23
- }
24
- const numId = parseInt(strId, 10);
25
- // Check for NaN
26
- if (isNaN(numId)) {
27
- throw new WordPressAPIError(`Invalid ${fieldName}: "${id}" is not a valid number`, 400, "INVALID_PARAMETER");
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":"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"}
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: `[![Line Coverage](...)]`
35
+ - Line 20: `[![Branch Coverage](...)]`
36
+ - Line 21: `[![Function Coverage](...)]`
37
+ - Line 22: `[![Test Results](...)]`
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.