mcp-wordpress 2.6.3 → 2.7.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 (333) hide show
  1. package/README.md +1 -1
  2. package/dist/cache/CacheInvalidation.d.ts +25 -6
  3. package/dist/cache/CacheInvalidation.d.ts.map +1 -1
  4. package/dist/cache/CacheInvalidation.js +168 -16
  5. package/dist/cache/CacheInvalidation.js.map +1 -1
  6. package/dist/cache/HttpCacheWrapper.d.ts.map +1 -1
  7. package/dist/cache/HttpCacheWrapper.js +3 -4
  8. package/dist/cache/HttpCacheWrapper.js.map +1 -1
  9. package/dist/cache/SEOCacheManager.d.ts +150 -0
  10. package/dist/cache/SEOCacheManager.d.ts.map +1 -0
  11. package/dist/cache/SEOCacheManager.js +275 -0
  12. package/dist/cache/SEOCacheManager.js.map +1 -0
  13. package/dist/client/SEOWordPressClient.d.ts +164 -0
  14. package/dist/client/SEOWordPressClient.d.ts.map +1 -0
  15. package/dist/client/SEOWordPressClient.js +674 -0
  16. package/dist/client/SEOWordPressClient.js.map +1 -0
  17. package/dist/client/api.d.ts.map +1 -1
  18. package/dist/client/api.js +50 -20
  19. package/dist/client/api.js.map +1 -1
  20. package/dist/client/auth.js +19 -19
  21. package/dist/client/auth.js.map +1 -1
  22. package/dist/client/index.d.ts +11 -0
  23. package/dist/client/index.d.ts.map +1 -0
  24. package/dist/client/index.js +14 -0
  25. package/dist/client/index.js.map +1 -0
  26. package/dist/client/managers/AuthManager.d.ts +39 -0
  27. package/dist/client/managers/AuthManager.d.ts.map +1 -0
  28. package/dist/client/managers/AuthManager.js +142 -0
  29. package/dist/client/managers/AuthManager.js.map +1 -0
  30. package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
  31. package/dist/client/managers/AuthenticationManager.js +10 -9
  32. package/dist/client/managers/AuthenticationManager.js.map +1 -1
  33. package/dist/client/managers/BaseManager.d.ts.map +1 -1
  34. package/dist/client/managers/BaseManager.js +12 -0
  35. package/dist/client/managers/BaseManager.js.map +1 -1
  36. package/dist/client/managers/ComposedAuthenticationManager.d.ts +94 -0
  37. package/dist/client/managers/ComposedAuthenticationManager.d.ts.map +1 -0
  38. package/dist/client/managers/ComposedAuthenticationManager.js +340 -0
  39. package/dist/client/managers/ComposedAuthenticationManager.js.map +1 -0
  40. package/dist/client/managers/ComposedManagerFactory.d.ts +104 -0
  41. package/dist/client/managers/ComposedManagerFactory.d.ts.map +1 -0
  42. package/dist/client/managers/ComposedManagerFactory.js +180 -0
  43. package/dist/client/managers/ComposedManagerFactory.js.map +1 -0
  44. package/dist/client/managers/ComposedRequestManager.d.ts +82 -0
  45. package/dist/client/managers/ComposedRequestManager.d.ts.map +1 -0
  46. package/dist/client/managers/ComposedRequestManager.js +260 -0
  47. package/dist/client/managers/ComposedRequestManager.js.map +1 -0
  48. package/dist/client/managers/JWTAuthImplementation.d.ts +86 -0
  49. package/dist/client/managers/JWTAuthImplementation.d.ts.map +1 -0
  50. package/dist/client/managers/JWTAuthImplementation.js +240 -0
  51. package/dist/client/managers/JWTAuthImplementation.js.map +1 -0
  52. package/dist/client/managers/ManagersIndex.d.ts +6 -0
  53. package/dist/client/managers/ManagersIndex.d.ts.map +1 -0
  54. package/dist/client/managers/ManagersIndex.js +6 -0
  55. package/dist/client/managers/ManagersIndex.js.map +1 -0
  56. package/dist/client/managers/RequestManager.d.ts.map +1 -1
  57. package/dist/client/managers/RequestManager.js +5 -3
  58. package/dist/client/managers/RequestManager.js.map +1 -1
  59. package/dist/client/managers/composed/MigrationAdapter.d.ts +80 -0
  60. package/dist/client/managers/composed/MigrationAdapter.d.ts.map +1 -0
  61. package/dist/client/managers/composed/MigrationAdapter.js +214 -0
  62. package/dist/client/managers/composed/MigrationAdapter.js.map +1 -0
  63. package/dist/client/managers/composed/index.d.ts +23 -0
  64. package/dist/client/managers/composed/index.d.ts.map +1 -0
  65. package/dist/client/managers/composed/index.js +26 -0
  66. package/dist/client/managers/composed/index.js.map +1 -0
  67. package/dist/client/managers/implementations/ConfigurationProviderImpl.d.ts +27 -0
  68. package/dist/client/managers/implementations/ConfigurationProviderImpl.d.ts.map +1 -0
  69. package/dist/client/managers/implementations/ConfigurationProviderImpl.js +41 -0
  70. package/dist/client/managers/implementations/ConfigurationProviderImpl.js.map +1 -0
  71. package/dist/client/managers/implementations/ErrorHandlerImpl.d.ts +31 -0
  72. package/dist/client/managers/implementations/ErrorHandlerImpl.d.ts.map +1 -0
  73. package/dist/client/managers/implementations/ErrorHandlerImpl.js +73 -0
  74. package/dist/client/managers/implementations/ErrorHandlerImpl.js.map +1 -0
  75. package/dist/client/managers/implementations/ParameterValidatorImpl.d.ts +47 -0
  76. package/dist/client/managers/implementations/ParameterValidatorImpl.d.ts.map +1 -0
  77. package/dist/client/managers/implementations/ParameterValidatorImpl.js +141 -0
  78. package/dist/client/managers/implementations/ParameterValidatorImpl.js.map +1 -0
  79. package/dist/client/managers/interfaces/ManagerInterfaces.d.ts +147 -0
  80. package/dist/client/managers/interfaces/ManagerInterfaces.d.ts.map +1 -0
  81. package/dist/client/managers/interfaces/ManagerInterfaces.js +6 -0
  82. package/dist/client/managers/interfaces/ManagerInterfaces.js.map +1 -0
  83. package/dist/config/Config.d.ts +30 -0
  84. package/dist/config/Config.d.ts.map +1 -1
  85. package/dist/config/Config.js +30 -0
  86. package/dist/config/Config.js.map +1 -1
  87. package/dist/config/ConfigurationSchema.d.ts +75 -198
  88. package/dist/config/ConfigurationSchema.d.ts.map +1 -1
  89. package/dist/config/ConfigurationSchema.js +17 -17
  90. package/dist/config/ConfigurationSchema.js.map +1 -1
  91. package/dist/config/ServerConfiguration.d.ts +2 -2
  92. package/dist/config/ServerConfiguration.d.ts.map +1 -1
  93. package/dist/config/ServerConfiguration.js +15 -13
  94. package/dist/config/ServerConfiguration.js.map +1 -1
  95. package/dist/config/index.d.ts +8 -0
  96. package/dist/config/index.d.ts.map +1 -0
  97. package/dist/config/index.js +11 -0
  98. package/dist/config/index.js.map +1 -0
  99. package/dist/docs/DocumentationGenerator.js +2 -2
  100. package/dist/docs/DocumentationGenerator.js.map +1 -1
  101. package/dist/dxt-entry.js +3 -3
  102. package/dist/dxt-entry.js.map +1 -1
  103. package/dist/index.d.ts +1 -0
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +38 -37
  106. package/dist/index.js.map +1 -1
  107. package/dist/performance/MetricsCollector.d.ts.map +1 -1
  108. package/dist/performance/MetricsCollector.js +5 -4
  109. package/dist/performance/MetricsCollector.js.map +1 -1
  110. package/dist/security/AISecurityScanner.js +7 -7
  111. package/dist/security/AISecurityScanner.js.map +1 -1
  112. package/dist/security/AutomatedRemediation.d.ts.map +1 -1
  113. package/dist/security/AutomatedRemediation.js +11 -11
  114. package/dist/security/AutomatedRemediation.js.map +1 -1
  115. package/dist/security/InputValidator.d.ts +50 -126
  116. package/dist/security/InputValidator.d.ts.map +1 -1
  117. package/dist/security/InputValidator.js +9 -9
  118. package/dist/security/InputValidator.js.map +1 -1
  119. package/dist/security/SecurityCIPipeline.d.ts +47 -5
  120. package/dist/security/SecurityCIPipeline.d.ts.map +1 -1
  121. package/dist/security/SecurityCIPipeline.js +390 -49
  122. package/dist/security/SecurityCIPipeline.js.map +1 -1
  123. package/dist/security/SecurityConfigManager.js +10 -10
  124. package/dist/security/SecurityConfigManager.js.map +1 -1
  125. package/dist/security/SecurityMonitoring.js +4 -4
  126. package/dist/security/SecurityMonitoring.js.map +1 -1
  127. package/dist/security/SecurityReviewer.d.ts.map +1 -1
  128. package/dist/security/SecurityReviewer.js +13 -6
  129. package/dist/security/SecurityReviewer.js.map +1 -1
  130. package/dist/security/index.js +3 -3
  131. package/dist/security/index.js.map +1 -1
  132. package/dist/server/ConnectionTester.js +5 -5
  133. package/dist/server/ConnectionTester.js.map +1 -1
  134. package/dist/server/ToolRegistry.d.ts +2 -2
  135. package/dist/server/ToolRegistry.d.ts.map +1 -1
  136. package/dist/server/ToolRegistry.js +7 -6
  137. package/dist/server/ToolRegistry.js.map +1 -1
  138. package/dist/server/index.d.ts +7 -0
  139. package/dist/server/index.d.ts.map +1 -0
  140. package/dist/server/index.js +9 -0
  141. package/dist/server/index.js.map +1 -0
  142. package/dist/tools/BaseToolManager.d.ts.map +1 -1
  143. package/dist/tools/BaseToolManager.js +11 -11
  144. package/dist/tools/BaseToolManager.js.map +1 -1
  145. package/dist/tools/auth.d.ts.map +1 -1
  146. package/dist/tools/auth.js +7 -7
  147. package/dist/tools/auth.js.map +1 -1
  148. package/dist/tools/comments.d.ts.map +1 -1
  149. package/dist/tools/comments.js +14 -14
  150. package/dist/tools/comments.js.map +1 -1
  151. package/dist/tools/index.d.ts +1 -0
  152. package/dist/tools/index.d.ts.map +1 -1
  153. package/dist/tools/index.js +1 -0
  154. package/dist/tools/index.js.map +1 -1
  155. package/dist/tools/media.d.ts.map +1 -1
  156. package/dist/tools/media.js +14 -11
  157. package/dist/tools/media.js.map +1 -1
  158. package/dist/tools/pages.d.ts.map +1 -1
  159. package/dist/tools/pages.js +12 -12
  160. package/dist/tools/pages.js.map +1 -1
  161. package/dist/tools/performance.d.ts.map +1 -1
  162. package/dist/tools/performance.js +13 -11
  163. package/dist/tools/performance.js.map +1 -1
  164. package/dist/tools/posts/PostHandlers.d.ts.map +1 -1
  165. package/dist/tools/posts/PostHandlers.js +16 -16
  166. package/dist/tools/posts/PostHandlers.js.map +1 -1
  167. package/dist/tools/posts/PostToolDefinitions.d.ts.map +1 -1
  168. package/dist/tools/posts/index.d.ts.map +1 -1
  169. package/dist/tools/seo/BulkOperations.d.ts +113 -0
  170. package/dist/tools/seo/BulkOperations.d.ts.map +1 -0
  171. package/dist/tools/seo/BulkOperations.js +398 -0
  172. package/dist/tools/seo/BulkOperations.js.map +1 -0
  173. package/dist/tools/seo/SEOHandlers.d.ts +55 -0
  174. package/dist/tools/seo/SEOHandlers.d.ts.map +1 -0
  175. package/dist/tools/seo/SEOHandlers.js +255 -0
  176. package/dist/tools/seo/SEOHandlers.js.map +1 -0
  177. package/dist/tools/seo/SEOToolDefinitions.d.ts +59 -0
  178. package/dist/tools/seo/SEOToolDefinitions.d.ts.map +1 -0
  179. package/dist/tools/seo/SEOToolDefinitions.js +385 -0
  180. package/dist/tools/seo/SEOToolDefinitions.js.map +1 -0
  181. package/dist/tools/seo/SEOTools.d.ts +203 -0
  182. package/dist/tools/seo/SEOTools.d.ts.map +1 -0
  183. package/dist/tools/seo/SEOTools.js +708 -0
  184. package/dist/tools/seo/SEOTools.js.map +1 -0
  185. package/dist/tools/seo/analyzers/ContentAnalyzer.d.ts +94 -0
  186. package/dist/tools/seo/analyzers/ContentAnalyzer.d.ts.map +1 -0
  187. package/dist/tools/seo/analyzers/ContentAnalyzer.js +402 -0
  188. package/dist/tools/seo/analyzers/ContentAnalyzer.js.map +1 -0
  189. package/dist/tools/seo/auditors/SiteAuditor.d.ts +121 -0
  190. package/dist/tools/seo/auditors/SiteAuditor.d.ts.map +1 -0
  191. package/dist/tools/seo/auditors/SiteAuditor.js +600 -0
  192. package/dist/tools/seo/auditors/SiteAuditor.js.map +1 -0
  193. package/dist/tools/seo/generators/MetaGenerator.d.ts +128 -0
  194. package/dist/tools/seo/generators/MetaGenerator.d.ts.map +1 -0
  195. package/dist/tools/seo/generators/MetaGenerator.js +547 -0
  196. package/dist/tools/seo/generators/MetaGenerator.js.map +1 -0
  197. package/dist/tools/seo/generators/SchemaGenerator.d.ts +204 -0
  198. package/dist/tools/seo/generators/SchemaGenerator.d.ts.map +1 -0
  199. package/dist/tools/seo/generators/SchemaGenerator.js +670 -0
  200. package/dist/tools/seo/generators/SchemaGenerator.js.map +1 -0
  201. package/dist/tools/seo/index.d.ts +17 -0
  202. package/dist/tools/seo/index.d.ts.map +1 -0
  203. package/dist/tools/seo/index.js +18 -0
  204. package/dist/tools/seo/index.js.map +1 -0
  205. package/dist/tools/seo/optimizers/InternalLinkingSuggester.d.ts +186 -0
  206. package/dist/tools/seo/optimizers/InternalLinkingSuggester.d.ts.map +1 -0
  207. package/dist/tools/seo/optimizers/InternalLinkingSuggester.js +683 -0
  208. package/dist/tools/seo/optimizers/InternalLinkingSuggester.js.map +1 -0
  209. package/dist/tools/site.d.ts.map +1 -1
  210. package/dist/tools/site.js +12 -12
  211. package/dist/tools/site.js.map +1 -1
  212. package/dist/tools/taxonomies.d.ts.map +1 -1
  213. package/dist/tools/taxonomies.js +20 -20
  214. package/dist/tools/taxonomies.js.map +1 -1
  215. package/dist/tools/users.d.ts.map +1 -1
  216. package/dist/tools/users.js +12 -12
  217. package/dist/tools/users.js.map +1 -1
  218. package/dist/types/client.d.ts +8 -6
  219. package/dist/types/client.d.ts.map +1 -1
  220. package/dist/types/client.js.map +1 -1
  221. package/dist/types/seo.d.ts +473 -0
  222. package/dist/types/seo.d.ts.map +1 -0
  223. package/dist/types/seo.js +94 -0
  224. package/dist/types/seo.js.map +1 -0
  225. package/dist/utils/enhancedError.js +1 -1
  226. package/dist/utils/enhancedError.js.map +1 -1
  227. package/dist/utils/error.d.ts.map +1 -1
  228. package/dist/utils/error.js +0 -1
  229. package/dist/utils/error.js.map +1 -1
  230. package/dist/utils/index.d.ts +12 -0
  231. package/dist/utils/index.d.ts.map +1 -0
  232. package/dist/utils/index.js +18 -0
  233. package/dist/utils/index.js.map +1 -0
  234. package/dist/utils/logger.js +3 -3
  235. package/dist/utils/logger.js.map +1 -1
  236. package/dist/utils/toolWrapper.d.ts +2 -2
  237. package/dist/utils/toolWrapper.js +8 -8
  238. package/dist/utils/toolWrapper.js.map +1 -1
  239. package/dist/utils/validation/core.d.ts.map +1 -1
  240. package/dist/utils/validation/core.js.map +1 -1
  241. package/dist/utils/validation/index.d.ts.map +1 -1
  242. package/dist/utils/validation/index.js.map +1 -1
  243. package/dist/utils/validation/network.js +3 -3
  244. package/dist/utils/validation/network.js.map +1 -1
  245. package/dist/utils/validation/rateLimit.js.map +1 -1
  246. package/dist/utils/validation/security.js.map +1 -1
  247. package/dist/utils/validation/wordpress.js.map +1 -1
  248. package/dist/utils/version.d.ts +144 -0
  249. package/dist/utils/version.d.ts.map +1 -0
  250. package/dist/utils/version.js +318 -0
  251. package/dist/utils/version.js.map +1 -0
  252. package/package.json +24 -58
  253. package/src/cache/CacheInvalidation.ts +183 -20
  254. package/src/cache/HttpCacheWrapper.ts +8 -5
  255. package/src/cache/SEOCacheManager.ts +330 -0
  256. package/src/cache/__tests__/CacheInvalidation.test.ts +6 -11
  257. package/src/cache/__tests__/CachedWordPressClient.test.ts +37 -62
  258. package/src/client/SEOWordPressClient.ts +876 -0
  259. package/src/client/api.ts +50 -21
  260. package/src/client/auth.ts +19 -19
  261. package/src/client/index.ts +16 -0
  262. package/src/client/managers/AuthManager.ts +175 -0
  263. package/src/client/managers/AuthenticationManager.ts +16 -14
  264. package/src/client/managers/BaseManager.ts +24 -5
  265. package/src/client/managers/ComposedAuthenticationManager.ts +409 -0
  266. package/src/client/managers/ComposedManagerFactory.ts +231 -0
  267. package/src/client/managers/ComposedRequestManager.ts +336 -0
  268. package/src/client/managers/JWTAuthImplementation.ts +326 -0
  269. package/src/client/managers/ManagersIndex.ts +6 -0
  270. package/src/client/managers/RequestManager.ts +9 -7
  271. package/src/client/managers/composed/MigrationAdapter.ts +263 -0
  272. package/src/client/managers/composed/index.ts +47 -0
  273. package/src/client/managers/implementations/ConfigurationProviderImpl.ts +52 -0
  274. package/src/client/managers/implementations/ErrorHandlerImpl.ts +102 -0
  275. package/src/client/managers/implementations/ParameterValidatorImpl.ts +221 -0
  276. package/src/client/managers/interfaces/ManagerInterfaces.ts +171 -0
  277. package/src/config/Config.ts +63 -0
  278. package/src/config/ConfigurationSchema.ts +17 -17
  279. package/src/config/ServerConfiguration.ts +18 -16
  280. package/src/config/index.ts +13 -0
  281. package/src/docs/DocumentationGenerator.ts +2 -2
  282. package/src/dxt-entry.ts +3 -3
  283. package/src/index.ts +43 -43
  284. package/src/performance/MetricsCollector.ts +15 -11
  285. package/src/security/AISecurityScanner.ts +7 -7
  286. package/src/security/AutomatedRemediation.ts +13 -11
  287. package/src/security/InputValidator.ts +10 -9
  288. package/src/security/SecurityCIPipeline.ts +494 -56
  289. package/src/security/SecurityConfigManager.ts +10 -10
  290. package/src/security/SecurityMonitoring.ts +5 -5
  291. package/src/security/SecurityReviewer.ts +13 -6
  292. package/src/security/index.ts +3 -3
  293. package/src/server/ConnectionTester.ts +5 -5
  294. package/src/server/ToolRegistry.ts +9 -8
  295. package/src/server/index.ts +10 -0
  296. package/src/tools/BaseToolManager.ts +55 -83
  297. package/src/tools/auth.ts +21 -12
  298. package/src/tools/comments.ts +23 -19
  299. package/src/tools/index.ts +1 -0
  300. package/src/tools/media.ts +23 -20
  301. package/src/tools/pages.ts +20 -13
  302. package/src/tools/performance.ts +101 -32
  303. package/src/tools/posts/PostHandlers.ts +23 -23
  304. package/src/tools/posts/PostToolDefinitions.ts +1 -1
  305. package/src/tools/posts/index.ts +2 -2
  306. package/src/tools/seo/BulkOperations.ts +557 -0
  307. package/src/tools/seo/SEOHandlers.ts +296 -0
  308. package/src/tools/seo/SEOToolDefinitions.ts +402 -0
  309. package/src/tools/seo/SEOTools.ts +871 -0
  310. package/src/tools/seo/analyzers/ContentAnalyzer.ts +493 -0
  311. package/src/tools/seo/auditors/SiteAuditor.ts +787 -0
  312. package/src/tools/seo/generators/MetaGenerator.ts +694 -0
  313. package/src/tools/seo/generators/SchemaGenerator.ts +955 -0
  314. package/src/tools/seo/index.ts +47 -0
  315. package/src/tools/seo/optimizers/InternalLinkingSuggester.ts +934 -0
  316. package/src/tools/site.ts +27 -26
  317. package/src/tools/taxonomies.ts +29 -25
  318. package/src/tools/users.ts +20 -13
  319. package/src/types/client.ts +8 -6
  320. package/src/types/seo.ts +546 -0
  321. package/src/utils/enhancedError.ts +1 -1
  322. package/src/utils/error.ts +1 -2
  323. package/src/utils/index.ts +23 -0
  324. package/src/utils/logger.ts +3 -3
  325. package/src/utils/toolWrapper.ts +10 -10
  326. package/src/utils/validation/core.ts +2 -2
  327. package/src/utils/validation/index.ts +2 -2
  328. package/src/utils/validation/network.ts +5 -5
  329. package/src/utils/validation/rateLimit.ts +1 -1
  330. package/src/utils/validation/security.ts +1 -1
  331. package/src/utils/validation/wordpress.ts +1 -1
  332. package/src/utils/version.ts +402 -0
  333. package/src/dxt-entry.cjs +0 -68
package/src/client/api.ts CHANGED
@@ -5,8 +5,9 @@
5
5
 
6
6
  // Use native fetch in Node.js 18+
7
7
  import FormData from "form-data";
8
- import * as fs from "fs";
8
+ import { promises as fsPromises } from "fs";
9
9
  import * as path from "path";
10
+ import { getUserAgent } from "../utils/version.js";
10
11
  import type {
11
12
  IWordPressClient,
12
13
  WordPressClientConfig,
@@ -166,7 +167,33 @@ export class WordPressClient implements IWordPressClient {
166
167
  this.maxRetries = options.maxRetries || cfg.wordpress.maxRetries;
167
168
 
168
169
  // Authentication configuration
169
- this.auth = options.auth || this.getAuthFromEnv();
170
+ if (options.auth) {
171
+ // If auth is provided but without method, infer it
172
+ if (!options.auth.method) {
173
+ const auth = options.auth as AuthConfig & {
174
+ username?: string;
175
+ appPassword?: string;
176
+ password?: string;
177
+ secret?: string;
178
+ apiKey?: string;
179
+ };
180
+ if (auth.username && auth.appPassword) {
181
+ this.auth = { ...auth, method: "app-password" };
182
+ } else if (auth.username && auth.password && auth.secret) {
183
+ this.auth = { ...auth, method: "jwt" };
184
+ } else if (auth.username && auth.password) {
185
+ this.auth = { ...auth, method: "basic" };
186
+ } else if (auth.apiKey) {
187
+ this.auth = { ...auth, method: "api-key" };
188
+ } else {
189
+ this.auth = { ...auth, method: "app-password" }; // default
190
+ }
191
+ } else {
192
+ this.auth = options.auth;
193
+ }
194
+ } else {
195
+ this.auth = this.getAuthFromEnv();
196
+ }
170
197
 
171
198
  // Rate limiting
172
199
  this.requestInterval = 60000 / cfg.security.rateLimit;
@@ -179,6 +206,7 @@ export class WordPressClient implements IWordPressClient {
179
206
  averageResponseTime: 0,
180
207
  rateLimitHits: 0,
181
208
  authFailures: 0,
209
+ errors: 0,
182
210
  };
183
211
 
184
212
  // Validate configuration
@@ -239,11 +267,11 @@ export class WordPressClient implements IWordPressClient {
239
267
 
240
268
  // Return clean URL without query parameters or fragments
241
269
  return `${parsed.protocol}//${parsed.host}${parsed.pathname}`.replace(/\/$/, "");
242
- } catch (error) {
243
- if (error instanceof TypeError) {
270
+ } catch (_error) {
271
+ if (_error instanceof TypeError) {
244
272
  throw new Error("Invalid WordPress site URL format");
245
273
  }
246
- throw error;
274
+ throw _error;
247
275
  }
248
276
  }
249
277
 
@@ -407,10 +435,10 @@ export class WordPressClient implements IWordPressClient {
407
435
  default:
408
436
  throw new Error(`Unsupported authentication method: ${method}`);
409
437
  }
410
- } catch (error) {
438
+ } catch (_error) {
411
439
  this._stats.authFailures++;
412
- logError(error as Error, { method });
413
- throw error;
440
+ logError(_error as Error, { method });
441
+ throw _error;
414
442
  }
415
443
  }
416
444
 
@@ -436,8 +464,8 @@ export class WordPressClient implements IWordPressClient {
436
464
  this.authenticated = true;
437
465
  debug.log("Basic/Application Password authentication successful");
438
466
  return true;
439
- } catch (error) {
440
- throw new AuthenticationError(`Basic authentication failed: ${(error as Error).message}`, this.auth.method);
467
+ } catch (_error) {
468
+ throw new AuthenticationError(`Basic authentication failed: ${(_error as Error).message}`, this.auth.method);
441
469
  }
442
470
  }
443
471
 
@@ -473,8 +501,8 @@ export class WordPressClient implements IWordPressClient {
473
501
  this.authenticated = true;
474
502
  debug.log("JWT authentication successful");
475
503
  return true;
476
- } catch (error) {
477
- throw new AuthenticationError(`JWT authentication failed: ${(error as Error).message}`, this.auth.method);
504
+ } catch (_error) {
505
+ throw new AuthenticationError(`JWT authentication failed: ${(_error as Error).message}`, this.auth.method);
478
506
  }
479
507
  }
480
508
 
@@ -508,7 +536,7 @@ export class WordPressClient implements IWordPressClient {
508
536
 
509
537
  const headers: Record<string, string> = {
510
538
  "Content-Type": "application/json",
511
- "User-Agent": "MCP-WordPress/1.0.0",
539
+ "User-Agent": getUserAgent(),
512
540
  ...options.headers,
513
541
  };
514
542
 
@@ -536,8 +564,7 @@ export class WordPressClient implements IWordPressClient {
536
564
  // For FormData, check if it has getHeaders method (form-data package)
537
565
  if (typeof (data as { getHeaders?: () => Record<string, string> }).getHeaders === "function") {
538
566
  // Use headers from form-data package
539
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
540
- const formHeaders = (data as any).getHeaders();
567
+ const formHeaders = (data as unknown as { getHeaders(): Record<string, string> }).getHeaders();
541
568
  Object.assign(headers, formHeaders);
542
569
  } else {
543
570
  // For native FormData, don't set Content-Type (let fetch set it with boundary)
@@ -681,12 +708,12 @@ export class WordPressClient implements IWordPressClient {
681
708
  this.updateAverageResponseTime(duration);
682
709
  return responseText as T;
683
710
  }
684
- } catch (error) {
711
+ } catch (_error) {
685
712
  clearTimeout(timeoutId);
686
- lastError = error as Error;
713
+ lastError = _error as Error;
687
714
 
688
715
  // Handle timeout errors
689
- if ((error as Error & { name?: string }).name === "AbortError") {
716
+ if ((_error as Error & { name?: string }).name === "AbortError") {
690
717
  lastError = new Error(`Request timeout after ${requestTimeout}ms`);
691
718
  }
692
719
 
@@ -819,13 +846,15 @@ export class WordPressClient implements IWordPressClient {
819
846
  }
820
847
 
821
848
  async uploadMedia(data: UploadMediaRequest): Promise<WordPressMedia> {
822
- if (!fs.existsSync(data.file_path)) {
849
+ try {
850
+ await fsPromises.access(data.file_path);
851
+ } catch {
823
852
  throw new Error(`File not found: ${data.file_path}`);
824
853
  }
825
854
 
826
- const stats = fs.statSync(data.file_path);
855
+ const stats = await fsPromises.stat(data.file_path);
827
856
  const filename = data.title || path.basename(data.file_path);
828
- const fileBuffer = fs.readFileSync(data.file_path);
857
+ const fileBuffer = await fsPromises.readFile(data.file_path);
829
858
 
830
859
  // Check if file is too large (WordPress default is 2MB for most installs)
831
860
  const maxSize = 10 * 1024 * 1024; // 10MB reasonable limit
@@ -42,9 +42,9 @@ export class WordPressAuth {
42
42
  default:
43
43
  throw new Error(`Unsupported authentication type: ${this.authType}`);
44
44
  }
45
- } catch (error) {
46
- logger.error("Authentication failed:", error);
47
- throw error;
45
+ } catch (_error) {
46
+ logger.error("Authentication failed:", _error);
47
+ throw _error;
48
48
  }
49
49
  }
50
50
 
@@ -66,10 +66,10 @@ export class WordPressAuth {
66
66
  const user = await this.client.getCurrentUser();
67
67
  logger.log(`✅ Application Password authentication successful for user: ${user.name} (${user.username})`);
68
68
  return true;
69
- } catch (error) {
69
+ } catch (_error) {
70
70
  const message =
71
71
  "Application Password authentication failed. Please check your credentials and ensure the application password is valid.";
72
- logger.error(message, error);
72
+ logger.error(message, _error);
73
73
  throw new Error(message);
74
74
  }
75
75
  }
@@ -88,9 +88,9 @@ export class WordPressAuth {
88
88
  const user = await this.client.getCurrentUser();
89
89
  logger.log(`✅ Basic authentication successful for user: ${user.name} (${user.username})`);
90
90
  return true;
91
- } catch (error) {
91
+ } catch (_error) {
92
92
  const message = "Basic authentication failed. Please check your username and password.";
93
- logger.error(message, error);
93
+ logger.error(message, _error);
94
94
  throw new Error(message);
95
95
  }
96
96
  }
@@ -113,10 +113,10 @@ export class WordPressAuth {
113
113
  const user = await this.client.getCurrentUser();
114
114
  logger.log(`✅ JWT authentication successful for user: ${user.name} (${user.username})`);
115
115
  return true;
116
- } catch (error) {
116
+ } catch (_error) {
117
117
  const message =
118
118
  "JWT authentication failed. Please check your credentials and ensure the JWT plugin is installed and configured.";
119
- logger.error(message, error);
119
+ logger.error(message, _error);
120
120
  throw new Error(message);
121
121
  }
122
122
  }
@@ -136,9 +136,9 @@ export class WordPressAuth {
136
136
  await this.client.getSiteInfo();
137
137
  logger.log("✅ API Key authentication successful");
138
138
  return true;
139
- } catch (error) {
139
+ } catch (_error) {
140
140
  const message = "API Key authentication failed. Please check your API key.";
141
- logger.error(message, error);
141
+ logger.error(message, _error);
142
142
  throw new Error(message);
143
143
  }
144
144
  }
@@ -158,9 +158,9 @@ export class WordPressAuth {
158
158
  await this.client.getSiteInfo();
159
159
  logger.log("✅ Cookie authentication configured (note: write operations may require valid nonce)");
160
160
  return true;
161
- } catch (error) {
161
+ } catch (_error) {
162
162
  const message = "Cookie authentication failed. Please ensure you are properly logged into WordPress.";
163
- logger.error(message, error);
163
+ logger.error(message, _error);
164
164
  throw new Error(message);
165
165
  }
166
166
  }
@@ -185,8 +185,8 @@ export class WordPressAuth {
185
185
  try {
186
186
  // Re-authenticate to get a new token
187
187
  return await this.handleJWTAuth();
188
- } catch (error) {
189
- logger.error("Failed to refresh JWT token:", error);
188
+ } catch (_error) {
189
+ logger.error("Failed to refresh JWT token:", _error);
190
190
  return false;
191
191
  }
192
192
  }
@@ -198,8 +198,8 @@ export class WordPressAuth {
198
198
  try {
199
199
  await this.client.getCurrentUser();
200
200
  return true;
201
- } catch (error) {
202
- logger.error("Authentication validation failed:", error);
201
+ } catch (_error) {
202
+ logger.error("Authentication validation failed:", _error);
203
203
  return false;
204
204
  }
205
205
  }
@@ -220,11 +220,11 @@ export class WordPressAuth {
220
220
  method: this.authType,
221
221
  user,
222
222
  };
223
- } catch (error) {
223
+ } catch (_error) {
224
224
  return {
225
225
  authenticated: false,
226
226
  method: this.authType,
227
- error: (error as Error).message,
227
+ error: (_error as Error).message,
228
228
  };
229
229
  }
230
230
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Client Barrel Export
3
+ * Centralized exports for all client classes and utilities
4
+ */
5
+
6
+ // Main Client Classes
7
+ export { WordPressClient } from './api.js';
8
+ export { CachedWordPressClient } from './CachedWordPressClient.js';
9
+ export { SEOWordPressClient } from './SEOWordPressClient.js';
10
+ export { MockWordPressClient } from './MockWordPressClient.js';
11
+
12
+ // Authentication utilities
13
+ export * from './auth.js';
14
+
15
+ // Manager exports (already has its own index)
16
+ export * from './managers/index.js';
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Authentication Manager
3
+ * Handles all authentication methods for WordPress REST API
4
+ */
5
+
6
+ import type { WordPressClient } from "../api.js";
7
+ import type { AuthConfig, AuthMethod } from "@/types/client.js";
8
+ import { AuthenticationError } from "@/types/client.js";
9
+ import { LoggerFactory } from "@/utils/logger.js";
10
+
11
+ export interface JWTToken {
12
+ token: string;
13
+ user_email: string;
14
+ user_nicename: string;
15
+ user_display_name: string;
16
+ expiresAt: number;
17
+ }
18
+
19
+ export class AuthManager {
20
+ private logger = LoggerFactory.api();
21
+ private jwtToken?: JWTToken;
22
+
23
+ constructor(
24
+ private client: WordPressClient,
25
+ private authConfig: AuthConfig
26
+ ) {}
27
+
28
+ /**
29
+ * Authenticate using the configured method
30
+ */
31
+ async authenticate(): Promise<boolean> {
32
+ this.logger.info("Authenticating with method", { method: this.authConfig.method });
33
+
34
+ try {
35
+ switch (this.authConfig.method) {
36
+ case "app-password":
37
+ return this.authenticateWithAppPassword();
38
+ case "jwt":
39
+ return this.authenticateWithJWT();
40
+ case "basic":
41
+ return this.authenticateWithBasic();
42
+ case "cookie":
43
+ return this.authenticateWithCookie();
44
+ case "api-key":
45
+ return this.authenticateWithAPIKey();
46
+ default:
47
+ throw new AuthenticationError(`Unsupported authentication method: ${this.authConfig.method}`, this.authConfig.method);
48
+ }
49
+ } catch (error) {
50
+ this.logger.error("Authentication failed", {
51
+ method: this.authConfig.method,
52
+ error: error instanceof Error ? error.message : String(error)
53
+ });
54
+ throw error;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Get current authentication headers
60
+ */
61
+ getAuthHeaders(): Record<string, string> {
62
+ const headers: Record<string, string> = {};
63
+
64
+ switch (this.authConfig.method) {
65
+ case "app-password":
66
+ case "basic":
67
+ if (this.authConfig.username && this.authConfig.appPassword) {
68
+ const credentials = Buffer.from(`${this.authConfig.username}:${this.authConfig.appPassword}`).toString("base64");
69
+ headers.Authorization = `Basic ${credentials}`;
70
+ }
71
+ break;
72
+
73
+ case "jwt":
74
+ if (this.jwtToken && !this.isTokenExpired()) {
75
+ headers.Authorization = `Bearer ${this.jwtToken.token}`;
76
+ }
77
+ break;
78
+
79
+ case "api-key":
80
+ if (this.authConfig.apiKey) {
81
+ headers["X-API-Key"] = this.authConfig.apiKey;
82
+ }
83
+ break;
84
+
85
+ case "cookie":
86
+ // Cookie authentication is handled by the browser/client
87
+ // Headers are set automatically after successful login
88
+ break;
89
+ }
90
+
91
+ return headers;
92
+ }
93
+
94
+ /**
95
+ * JWT authentication
96
+ */
97
+ private async authenticateWithJWT(): Promise<boolean> {
98
+ if (!this.authConfig.username || !this.authConfig.password) {
99
+ throw new AuthenticationError("Username and password are required for JWT authentication", this.authConfig.method);
100
+ }
101
+
102
+ try {
103
+ const response = await this.client.post<{
104
+ token: string;
105
+ user_email: string;
106
+ user_nicename: string;
107
+ user_display_name: string;
108
+ }>("jwt-auth/v1/token", {
109
+ username: this.authConfig.username,
110
+ password: this.authConfig.password,
111
+ });
112
+
113
+ if (!response.token) {
114
+ throw new AuthenticationError("JWT token not received", this.authConfig.method);
115
+ }
116
+
117
+ // Calculate expiration time (typically 24 hours for JWT)
118
+ const expiresAt = Date.now() + (24 * 60 * 60 * 1000); // 24 hours
119
+
120
+ this.jwtToken = {
121
+ token: response.token,
122
+ user_email: response.user_email,
123
+ user_nicename: response.user_nicename,
124
+ user_display_name: response.user_display_name,
125
+ expiresAt,
126
+ };
127
+
128
+ this.logger.info("JWT authentication successful", {
129
+ user: response.user_nicename,
130
+ expiresAt: new Date(expiresAt).toISOString(),
131
+ });
132
+
133
+ return true;
134
+ } catch (error) {
135
+ if (error instanceof Error) {
136
+ throw new AuthenticationError(`JWT authentication failed: ${error.message}`, this.authConfig.method);
137
+ }
138
+ throw new AuthenticationError("JWT authentication failed", this.authConfig.method);
139
+ }
140
+ }
141
+
142
+ private authenticateWithAppPassword(): boolean {
143
+ if (!this.authConfig.username || !this.authConfig.appPassword) {
144
+ throw new AuthenticationError("Username and app password are required", this.authConfig.method);
145
+ }
146
+ return true;
147
+ }
148
+
149
+ private authenticateWithBasic(): boolean {
150
+ if (!this.authConfig.username || !this.authConfig.password) {
151
+ throw new AuthenticationError("Username and password are required", this.authConfig.method);
152
+ }
153
+ return true;
154
+ }
155
+
156
+ private async authenticateWithCookie(): Promise<boolean> {
157
+ throw new AuthenticationError("Cookie authentication not implemented", this.authConfig.method);
158
+ }
159
+
160
+ private authenticateWithAPIKey(): boolean {
161
+ if (!this.authConfig.apiKey) {
162
+ throw new AuthenticationError("API key is required", this.authConfig.method);
163
+ }
164
+ return true;
165
+ }
166
+
167
+ private isTokenExpired(): boolean {
168
+ if (!this.jwtToken) return true;
169
+ return Date.now() > this.jwtToken.expiresAt;
170
+ }
171
+
172
+ getAuthMethod(): AuthMethod {
173
+ return this.authConfig.method;
174
+ }
175
+ }
@@ -11,12 +11,12 @@ import type {
11
11
  JwtCredentials,
12
12
  BasicCredentials,
13
13
  ApiKeyCredentials,
14
- } from "../../types/client.js";
15
- import { AuthenticationError } from "../../types/client.js";
16
- import { AUTH_METHODS, type AuthMethod } from "../../types/wordpress.js";
17
- import { config } from "../../config/Config.js";
14
+ } from "@/types/client.js";
15
+ import { AuthenticationError } from "@/types/client.js";
16
+ import { AUTH_METHODS, type AuthMethod } from "@/types/wordpress.js";
17
+ import { config } from "@/config/Config.js";
18
18
  import { BaseManager } from "./BaseManager.js";
19
- import { debug } from "../../utils/debug.js";
19
+ import { debug } from "@/utils/debug.js";
20
20
 
21
21
  interface AuthManagerConfig extends WordPressClientConfig {
22
22
  siteUrl: string; // Required based on constructor validation
@@ -42,12 +42,16 @@ export class AuthenticationManager extends BaseManager {
42
42
  throw new AuthenticationError("Site URL is required", AUTH_METHODS.APP_PASSWORD);
43
43
  }
44
44
 
45
- // Validate site URL format
45
+ // Validate and normalize site URL format
46
46
  try {
47
47
  new URL(config.siteUrl);
48
48
  } catch {
49
49
  throw new AuthenticationError("Invalid site URL", AUTH_METHODS.APP_PASSWORD);
50
50
  }
51
+
52
+ // Normalize URL by removing trailing slash
53
+ const normalizedSiteUrl = config.siteUrl.replace(/\/$/, '');
54
+ config.siteUrl = normalizedSiteUrl;
51
55
 
52
56
  // Validate auth method using centralized constants
53
57
  const validMethods = Object.values(AUTH_METHODS);
@@ -200,8 +204,8 @@ export class AuthenticationManager extends BaseManager {
200
204
  "JWT authentication requires RequestManager integration - not yet implemented",
201
205
  AUTH_METHODS.JWT,
202
206
  );
203
- } catch (error) {
204
- this.handleError(error, "JWT authentication");
207
+ } catch (_error) {
208
+ this.handleError(_error, "JWT authentication");
205
209
  }
206
210
  }
207
211
 
@@ -219,9 +223,9 @@ export class AuthenticationManager extends BaseManager {
219
223
  // For now, we'll return true if headers can be generated
220
224
  this.authenticated = true;
221
225
  return true;
222
- } catch (error) {
226
+ } catch (_error) {
223
227
  this.authenticated = false;
224
- debug.log("Authentication test failed", error);
228
+ debug.log("Authentication test failed", _error);
225
229
  return false;
226
230
  }
227
231
  }
@@ -450,14 +454,12 @@ export class AuthenticationManager extends BaseManager {
450
454
  const isExpired = this.isTokenExpired();
451
455
 
452
456
  const status: AuthStatus = {
453
- method,
454
- username: this.authConfig.username,
455
457
  isAuthenticated: method === AUTH_METHODS.JWT ? !isExpired : true,
456
- tokenExpired: isExpired,
458
+ method,
457
459
  };
458
460
 
459
461
  if (method === AUTH_METHODS.JWT && this.authConfig.tokenExpiry) {
460
- status.tokenExpiry = this.authConfig.tokenExpiry;
462
+ status.tokenExpiry = new Date(this.authConfig.tokenExpiry);
461
463
  }
462
464
 
463
465
  return status;
@@ -3,10 +3,10 @@
3
3
  * Provides common functionality and error handling
4
4
  */
5
5
 
6
- import type { WordPressClientConfig } from "../../types/client.js";
7
- import { WordPressAPIError } from "../../types/client.js";
8
- import { debug, logError } from "../../utils/debug.js";
9
- import { getErrorMessage } from "../../utils/error.js";
6
+ import type { WordPressClientConfig } from "@/types/client.js";
7
+ import { WordPressAPIError } from "@/types/client.js";
8
+ import { debug, logError } from "@/utils/debug.js";
9
+ import { getErrorMessage } from "@/utils/error.js";
10
10
 
11
11
  export abstract class BaseManager {
12
12
  protected config: WordPressClientConfig;
@@ -36,7 +36,26 @@ export abstract class BaseManager {
36
36
  }
37
37
 
38
38
  if (error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") {
39
- throw new WordPressAPIError(`Cannot connect to WordPress site: ${this.config.baseUrl}`, 503, "connection_failed");
39
+ throw new WordPressAPIError(
40
+ `Cannot connect to WordPress site: ${this.config.baseUrl}`,
41
+ 503,
42
+ "connection_failed",
43
+ );
44
+ }
45
+
46
+ // Preserve custom error properties if they exist
47
+ const errorObj = error as Record<string, unknown>;
48
+ const customCode = errorObj.code;
49
+ const customDetails = errorObj.details;
50
+ if (
51
+ customCode &&
52
+ typeof customCode === "string" &&
53
+ customCode !== "ECONNREFUSED" &&
54
+ customCode !== "ENOTFOUND" &&
55
+ customCode !== "ABORT_ERR"
56
+ ) {
57
+ const message = getErrorMessage(error);
58
+ throw new WordPressAPIError(`${operation} failed: ${message}`, 500, customCode, customDetails);
40
59
  }
41
60
  }
42
61