mcp-wordpress 2.6.4 → 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.
- package/README.md +1 -1
- package/dist/cache/CacheInvalidation.d.ts +25 -6
- package/dist/cache/CacheInvalidation.d.ts.map +1 -1
- package/dist/cache/CacheInvalidation.js +168 -16
- package/dist/cache/CacheInvalidation.js.map +1 -1
- package/dist/cache/HttpCacheWrapper.d.ts.map +1 -1
- package/dist/cache/HttpCacheWrapper.js +3 -4
- package/dist/cache/HttpCacheWrapper.js.map +1 -1
- package/dist/cache/SEOCacheManager.d.ts +150 -0
- package/dist/cache/SEOCacheManager.d.ts.map +1 -0
- package/dist/cache/SEOCacheManager.js +275 -0
- package/dist/cache/SEOCacheManager.js.map +1 -0
- package/dist/client/SEOWordPressClient.d.ts +164 -0
- package/dist/client/SEOWordPressClient.d.ts.map +1 -0
- package/dist/client/SEOWordPressClient.js +674 -0
- package/dist/client/SEOWordPressClient.js.map +1 -0
- package/dist/client/api.d.ts.map +1 -1
- package/dist/client/api.js +50 -20
- package/dist/client/api.js.map +1 -1
- package/dist/client/auth.js +19 -19
- package/dist/client/auth.js.map +1 -1
- package/dist/client/index.d.ts +11 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +14 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/managers/AuthManager.d.ts +39 -0
- package/dist/client/managers/AuthManager.d.ts.map +1 -0
- package/dist/client/managers/AuthManager.js +142 -0
- package/dist/client/managers/AuthManager.js.map +1 -0
- package/dist/client/managers/AuthenticationManager.d.ts.map +1 -1
- package/dist/client/managers/AuthenticationManager.js +10 -9
- package/dist/client/managers/AuthenticationManager.js.map +1 -1
- package/dist/client/managers/BaseManager.d.ts.map +1 -1
- package/dist/client/managers/BaseManager.js +12 -0
- package/dist/client/managers/BaseManager.js.map +1 -1
- package/dist/client/managers/ComposedAuthenticationManager.d.ts +94 -0
- package/dist/client/managers/ComposedAuthenticationManager.d.ts.map +1 -0
- package/dist/client/managers/ComposedAuthenticationManager.js +340 -0
- package/dist/client/managers/ComposedAuthenticationManager.js.map +1 -0
- package/dist/client/managers/ComposedManagerFactory.d.ts +104 -0
- package/dist/client/managers/ComposedManagerFactory.d.ts.map +1 -0
- package/dist/client/managers/ComposedManagerFactory.js +180 -0
- package/dist/client/managers/ComposedManagerFactory.js.map +1 -0
- package/dist/client/managers/ComposedRequestManager.d.ts +82 -0
- package/dist/client/managers/ComposedRequestManager.d.ts.map +1 -0
- package/dist/client/managers/ComposedRequestManager.js +260 -0
- package/dist/client/managers/ComposedRequestManager.js.map +1 -0
- package/dist/client/managers/JWTAuthImplementation.d.ts +86 -0
- package/dist/client/managers/JWTAuthImplementation.d.ts.map +1 -0
- package/dist/client/managers/JWTAuthImplementation.js +240 -0
- package/dist/client/managers/JWTAuthImplementation.js.map +1 -0
- package/dist/client/managers/ManagersIndex.d.ts +6 -0
- package/dist/client/managers/ManagersIndex.d.ts.map +1 -0
- package/dist/client/managers/ManagersIndex.js +6 -0
- package/dist/client/managers/ManagersIndex.js.map +1 -0
- package/dist/client/managers/RequestManager.d.ts.map +1 -1
- package/dist/client/managers/RequestManager.js +5 -3
- package/dist/client/managers/RequestManager.js.map +1 -1
- package/dist/client/managers/composed/MigrationAdapter.d.ts +80 -0
- package/dist/client/managers/composed/MigrationAdapter.d.ts.map +1 -0
- package/dist/client/managers/composed/MigrationAdapter.js +214 -0
- package/dist/client/managers/composed/MigrationAdapter.js.map +1 -0
- package/dist/client/managers/composed/index.d.ts +23 -0
- package/dist/client/managers/composed/index.d.ts.map +1 -0
- package/dist/client/managers/composed/index.js +26 -0
- package/dist/client/managers/composed/index.js.map +1 -0
- package/dist/client/managers/implementations/ConfigurationProviderImpl.d.ts +27 -0
- package/dist/client/managers/implementations/ConfigurationProviderImpl.d.ts.map +1 -0
- package/dist/client/managers/implementations/ConfigurationProviderImpl.js +41 -0
- package/dist/client/managers/implementations/ConfigurationProviderImpl.js.map +1 -0
- package/dist/client/managers/implementations/ErrorHandlerImpl.d.ts +31 -0
- package/dist/client/managers/implementations/ErrorHandlerImpl.d.ts.map +1 -0
- package/dist/client/managers/implementations/ErrorHandlerImpl.js +73 -0
- package/dist/client/managers/implementations/ErrorHandlerImpl.js.map +1 -0
- package/dist/client/managers/implementations/ParameterValidatorImpl.d.ts +47 -0
- package/dist/client/managers/implementations/ParameterValidatorImpl.d.ts.map +1 -0
- package/dist/client/managers/implementations/ParameterValidatorImpl.js +141 -0
- package/dist/client/managers/implementations/ParameterValidatorImpl.js.map +1 -0
- package/dist/client/managers/interfaces/ManagerInterfaces.d.ts +147 -0
- package/dist/client/managers/interfaces/ManagerInterfaces.d.ts.map +1 -0
- package/dist/client/managers/interfaces/ManagerInterfaces.js +6 -0
- package/dist/client/managers/interfaces/ManagerInterfaces.js.map +1 -0
- package/dist/config/Config.d.ts +30 -0
- package/dist/config/Config.d.ts.map +1 -1
- package/dist/config/Config.js +30 -0
- package/dist/config/Config.js.map +1 -1
- package/dist/config/ConfigurationSchema.d.ts +75 -198
- package/dist/config/ConfigurationSchema.d.ts.map +1 -1
- package/dist/config/ConfigurationSchema.js +17 -17
- package/dist/config/ConfigurationSchema.js.map +1 -1
- package/dist/config/ServerConfiguration.d.ts +2 -2
- package/dist/config/ServerConfiguration.d.ts.map +1 -1
- package/dist/config/ServerConfiguration.js +15 -13
- package/dist/config/ServerConfiguration.js.map +1 -1
- package/dist/config/index.d.ts +8 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +11 -0
- package/dist/config/index.js.map +1 -0
- package/dist/docs/DocumentationGenerator.js +2 -2
- package/dist/docs/DocumentationGenerator.js.map +1 -1
- package/dist/dxt-entry.js +3 -3
- package/dist/dxt-entry.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -37
- package/dist/index.js.map +1 -1
- package/dist/performance/MetricsCollector.d.ts.map +1 -1
- package/dist/performance/MetricsCollector.js +5 -4
- package/dist/performance/MetricsCollector.js.map +1 -1
- package/dist/security/AISecurityScanner.js +7 -7
- package/dist/security/AISecurityScanner.js.map +1 -1
- package/dist/security/AutomatedRemediation.d.ts.map +1 -1
- package/dist/security/AutomatedRemediation.js +11 -11
- package/dist/security/AutomatedRemediation.js.map +1 -1
- package/dist/security/InputValidator.d.ts +50 -126
- package/dist/security/InputValidator.d.ts.map +1 -1
- package/dist/security/InputValidator.js +9 -9
- package/dist/security/InputValidator.js.map +1 -1
- package/dist/security/SecurityCIPipeline.d.ts +47 -5
- package/dist/security/SecurityCIPipeline.d.ts.map +1 -1
- package/dist/security/SecurityCIPipeline.js +390 -49
- package/dist/security/SecurityCIPipeline.js.map +1 -1
- package/dist/security/SecurityConfigManager.js +10 -10
- package/dist/security/SecurityConfigManager.js.map +1 -1
- package/dist/security/SecurityMonitoring.js +4 -4
- package/dist/security/SecurityMonitoring.js.map +1 -1
- package/dist/security/SecurityReviewer.d.ts.map +1 -1
- package/dist/security/SecurityReviewer.js +13 -6
- package/dist/security/SecurityReviewer.js.map +1 -1
- package/dist/security/index.js +3 -3
- package/dist/security/index.js.map +1 -1
- package/dist/server/ConnectionTester.js +5 -5
- 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 +7 -6
- package/dist/server/ToolRegistry.js.map +1 -1
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -0
- package/dist/tools/BaseToolManager.d.ts.map +1 -1
- package/dist/tools/BaseToolManager.js +11 -11
- package/dist/tools/BaseToolManager.js.map +1 -1
- package/dist/tools/auth.d.ts.map +1 -1
- package/dist/tools/auth.js +7 -7
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/comments.d.ts.map +1 -1
- package/dist/tools/comments.js +14 -14
- package/dist/tools/comments.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/media.d.ts.map +1 -1
- package/dist/tools/media.js +14 -11
- package/dist/tools/media.js.map +1 -1
- package/dist/tools/pages.d.ts.map +1 -1
- package/dist/tools/pages.js +12 -12
- package/dist/tools/pages.js.map +1 -1
- package/dist/tools/performance.d.ts.map +1 -1
- package/dist/tools/performance.js +13 -11
- package/dist/tools/performance.js.map +1 -1
- package/dist/tools/posts/PostHandlers.d.ts.map +1 -1
- package/dist/tools/posts/PostHandlers.js +16 -16
- package/dist/tools/posts/PostHandlers.js.map +1 -1
- package/dist/tools/posts/PostToolDefinitions.d.ts.map +1 -1
- package/dist/tools/posts/index.d.ts.map +1 -1
- package/dist/tools/seo/BulkOperations.d.ts +113 -0
- package/dist/tools/seo/BulkOperations.d.ts.map +1 -0
- package/dist/tools/seo/BulkOperations.js +398 -0
- package/dist/tools/seo/BulkOperations.js.map +1 -0
- package/dist/tools/seo/SEOHandlers.d.ts +55 -0
- package/dist/tools/seo/SEOHandlers.d.ts.map +1 -0
- package/dist/tools/seo/SEOHandlers.js +255 -0
- package/dist/tools/seo/SEOHandlers.js.map +1 -0
- package/dist/tools/seo/SEOToolDefinitions.d.ts +59 -0
- package/dist/tools/seo/SEOToolDefinitions.d.ts.map +1 -0
- package/dist/tools/seo/SEOToolDefinitions.js +385 -0
- package/dist/tools/seo/SEOToolDefinitions.js.map +1 -0
- package/dist/tools/seo/SEOTools.d.ts +203 -0
- package/dist/tools/seo/SEOTools.d.ts.map +1 -0
- package/dist/tools/seo/SEOTools.js +708 -0
- package/dist/tools/seo/SEOTools.js.map +1 -0
- package/dist/tools/seo/analyzers/ContentAnalyzer.d.ts +94 -0
- package/dist/tools/seo/analyzers/ContentAnalyzer.d.ts.map +1 -0
- package/dist/tools/seo/analyzers/ContentAnalyzer.js +402 -0
- package/dist/tools/seo/analyzers/ContentAnalyzer.js.map +1 -0
- package/dist/tools/seo/auditors/SiteAuditor.d.ts +121 -0
- package/dist/tools/seo/auditors/SiteAuditor.d.ts.map +1 -0
- package/dist/tools/seo/auditors/SiteAuditor.js +600 -0
- package/dist/tools/seo/auditors/SiteAuditor.js.map +1 -0
- package/dist/tools/seo/generators/MetaGenerator.d.ts +128 -0
- package/dist/tools/seo/generators/MetaGenerator.d.ts.map +1 -0
- package/dist/tools/seo/generators/MetaGenerator.js +547 -0
- package/dist/tools/seo/generators/MetaGenerator.js.map +1 -0
- package/dist/tools/seo/generators/SchemaGenerator.d.ts +204 -0
- package/dist/tools/seo/generators/SchemaGenerator.d.ts.map +1 -0
- package/dist/tools/seo/generators/SchemaGenerator.js +670 -0
- package/dist/tools/seo/generators/SchemaGenerator.js.map +1 -0
- package/dist/tools/seo/index.d.ts +17 -0
- package/dist/tools/seo/index.d.ts.map +1 -0
- package/dist/tools/seo/index.js +18 -0
- package/dist/tools/seo/index.js.map +1 -0
- package/dist/tools/seo/optimizers/InternalLinkingSuggester.d.ts +186 -0
- package/dist/tools/seo/optimizers/InternalLinkingSuggester.d.ts.map +1 -0
- package/dist/tools/seo/optimizers/InternalLinkingSuggester.js +683 -0
- package/dist/tools/seo/optimizers/InternalLinkingSuggester.js.map +1 -0
- package/dist/tools/site.d.ts.map +1 -1
- package/dist/tools/site.js +12 -12
- package/dist/tools/site.js.map +1 -1
- package/dist/tools/taxonomies.d.ts.map +1 -1
- package/dist/tools/taxonomies.js +20 -20
- package/dist/tools/taxonomies.js.map +1 -1
- package/dist/tools/users.d.ts.map +1 -1
- package/dist/tools/users.js +12 -12
- package/dist/tools/users.js.map +1 -1
- package/dist/types/client.d.ts +8 -6
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/client.js.map +1 -1
- package/dist/types/seo.d.ts +473 -0
- package/dist/types/seo.d.ts.map +1 -0
- package/dist/types/seo.js +94 -0
- package/dist/types/seo.js.map +1 -0
- package/dist/utils/enhancedError.js +1 -1
- package/dist/utils/enhancedError.js.map +1 -1
- package/dist/utils/error.d.ts.map +1 -1
- package/dist/utils/error.js +0 -1
- package/dist/utils/error.js.map +1 -1
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.js +3 -3
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/toolWrapper.d.ts +2 -2
- package/dist/utils/toolWrapper.js +8 -8
- package/dist/utils/toolWrapper.js.map +1 -1
- package/dist/utils/validation/core.d.ts.map +1 -1
- package/dist/utils/validation/core.js.map +1 -1
- package/dist/utils/validation/index.d.ts.map +1 -1
- package/dist/utils/validation/index.js.map +1 -1
- package/dist/utils/validation/network.js +3 -3
- package/dist/utils/validation/network.js.map +1 -1
- package/dist/utils/validation/rateLimit.js.map +1 -1
- package/dist/utils/validation/security.js.map +1 -1
- package/dist/utils/validation/wordpress.js.map +1 -1
- package/dist/utils/version.d.ts +144 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +318 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +21 -55
- package/src/cache/CacheInvalidation.ts +183 -20
- package/src/cache/HttpCacheWrapper.ts +8 -5
- package/src/cache/SEOCacheManager.ts +330 -0
- package/src/cache/__tests__/CacheInvalidation.test.ts +6 -11
- package/src/cache/__tests__/CachedWordPressClient.test.ts +37 -62
- package/src/client/SEOWordPressClient.ts +876 -0
- package/src/client/api.ts +50 -21
- package/src/client/auth.ts +19 -19
- package/src/client/index.ts +16 -0
- package/src/client/managers/AuthManager.ts +175 -0
- package/src/client/managers/AuthenticationManager.ts +16 -14
- package/src/client/managers/BaseManager.ts +24 -5
- package/src/client/managers/ComposedAuthenticationManager.ts +409 -0
- package/src/client/managers/ComposedManagerFactory.ts +231 -0
- package/src/client/managers/ComposedRequestManager.ts +336 -0
- package/src/client/managers/JWTAuthImplementation.ts +326 -0
- package/src/client/managers/ManagersIndex.ts +6 -0
- package/src/client/managers/RequestManager.ts +9 -7
- package/src/client/managers/composed/MigrationAdapter.ts +263 -0
- package/src/client/managers/composed/index.ts +47 -0
- package/src/client/managers/implementations/ConfigurationProviderImpl.ts +52 -0
- package/src/client/managers/implementations/ErrorHandlerImpl.ts +102 -0
- package/src/client/managers/implementations/ParameterValidatorImpl.ts +221 -0
- package/src/client/managers/interfaces/ManagerInterfaces.ts +171 -0
- package/src/config/Config.ts +63 -0
- package/src/config/ConfigurationSchema.ts +17 -17
- package/src/config/ServerConfiguration.ts +18 -16
- package/src/config/index.ts +13 -0
- package/src/docs/DocumentationGenerator.ts +2 -2
- package/src/dxt-entry.ts +3 -3
- package/src/index.ts +43 -43
- package/src/performance/MetricsCollector.ts +15 -11
- package/src/security/AISecurityScanner.ts +7 -7
- package/src/security/AutomatedRemediation.ts +13 -11
- package/src/security/InputValidator.ts +10 -9
- package/src/security/SecurityCIPipeline.ts +494 -56
- package/src/security/SecurityConfigManager.ts +10 -10
- package/src/security/SecurityMonitoring.ts +5 -5
- package/src/security/SecurityReviewer.ts +13 -6
- package/src/security/index.ts +3 -3
- package/src/server/ConnectionTester.ts +5 -5
- package/src/server/ToolRegistry.ts +9 -8
- package/src/server/index.ts +10 -0
- package/src/tools/BaseToolManager.ts +55 -83
- package/src/tools/auth.ts +21 -12
- package/src/tools/comments.ts +23 -19
- package/src/tools/index.ts +1 -0
- package/src/tools/media.ts +23 -20
- package/src/tools/pages.ts +20 -13
- package/src/tools/performance.ts +101 -32
- package/src/tools/posts/PostHandlers.ts +23 -23
- package/src/tools/posts/PostToolDefinitions.ts +1 -1
- package/src/tools/posts/index.ts +2 -2
- package/src/tools/seo/BulkOperations.ts +557 -0
- package/src/tools/seo/SEOHandlers.ts +296 -0
- package/src/tools/seo/SEOToolDefinitions.ts +402 -0
- package/src/tools/seo/SEOTools.ts +871 -0
- package/src/tools/seo/analyzers/ContentAnalyzer.ts +493 -0
- package/src/tools/seo/auditors/SiteAuditor.ts +787 -0
- package/src/tools/seo/generators/MetaGenerator.ts +694 -0
- package/src/tools/seo/generators/SchemaGenerator.ts +955 -0
- package/src/tools/seo/index.ts +47 -0
- package/src/tools/seo/optimizers/InternalLinkingSuggester.ts +934 -0
- package/src/tools/site.ts +27 -26
- package/src/tools/taxonomies.ts +29 -25
- package/src/tools/users.ts +20 -13
- package/src/types/client.ts +8 -6
- package/src/types/seo.ts +546 -0
- package/src/utils/enhancedError.ts +1 -1
- package/src/utils/error.ts +1 -2
- package/src/utils/index.ts +23 -0
- package/src/utils/logger.ts +3 -3
- package/src/utils/toolWrapper.ts +10 -10
- package/src/utils/validation/core.ts +2 -2
- package/src/utils/validation/index.ts +2 -2
- package/src/utils/validation/network.ts +5 -5
- package/src/utils/validation/rateLimit.ts +1 -1
- package/src/utils/validation/security.ts +1 -1
- package/src/utils/validation/wordpress.ts +1 -1
- package/src/utils/version.ts +402 -0
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress SEO Tools - Main Module
|
|
3
|
+
*
|
|
4
|
+
* This module provides comprehensive SEO management functionality for WordPress
|
|
5
|
+
* through the MCP protocol. It combines content analysis, metadata generation,
|
|
6
|
+
* schema markup, and optimization capabilities in a modular architecture.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Content analysis for readability and keyword optimization
|
|
10
|
+
* - Metadata generation with AI assistance and safety filters
|
|
11
|
+
* - Schema markup generation and validation
|
|
12
|
+
* - Internal linking optimization
|
|
13
|
+
* - Site audits and Core Web Vitals monitoring
|
|
14
|
+
* - Bulk operations with progress tracking
|
|
15
|
+
*
|
|
16
|
+
* @since 2.7.0
|
|
17
|
+
*/
|
|
18
|
+
import { WordPressClient } from "../../client/api.js";
|
|
19
|
+
import { SEOWordPressClient } from "../../client/SEOWordPressClient.js";
|
|
20
|
+
import { LoggerFactory } from "../../utils/logger.js";
|
|
21
|
+
import { validateRequired, handleToolError } from "../../utils/error.js";
|
|
22
|
+
import { ContentAnalyzer } from "./analyzers/ContentAnalyzer.js";
|
|
23
|
+
import { MetaGenerator } from "./generators/MetaGenerator.js";
|
|
24
|
+
import { SchemaGenerator } from "./generators/SchemaGenerator.js";
|
|
25
|
+
import { InternalLinkingSuggester } from "./optimizers/InternalLinkingSuggester.js";
|
|
26
|
+
import { SiteAuditor } from "./auditors/SiteAuditor.js";
|
|
27
|
+
import { BulkOperations } from "./BulkOperations.js";
|
|
28
|
+
import { SEOCacheManager } from "../../cache/SEOCacheManager.js";
|
|
29
|
+
import { seoToolDefinitions } from "./SEOToolDefinitions.js";
|
|
30
|
+
import { handleAnalyzeContent, handleGenerateMetadata, handleBulkUpdateMetadata, handleGenerateSchema, handleValidateSchema, handleSuggestInternalLinks, handlePerformSiteAudit, handleTrackSERPPositions, handleKeywordResearch, handleTestSEOIntegration, handleGetLiveSEOData, } from "./SEOHandlers.js";
|
|
31
|
+
/**
|
|
32
|
+
* Main SEOTools class that provides WordPress SEO management functionality.
|
|
33
|
+
*
|
|
34
|
+
* This class serves as the interface between the MCP framework and WordPress
|
|
35
|
+
* SEO operations. It follows the established pattern of other tool classes
|
|
36
|
+
* while providing SEO-specific capabilities.
|
|
37
|
+
*
|
|
38
|
+
* The class is designed with a modular architecture:
|
|
39
|
+
* - Analyzers for content evaluation
|
|
40
|
+
* - Generators for metadata and schema creation
|
|
41
|
+
* - Validators for ensuring compliance
|
|
42
|
+
* - Optimizers for performance improvements
|
|
43
|
+
*
|
|
44
|
+
* @since 2.7.0
|
|
45
|
+
*/
|
|
46
|
+
export class SEOTools {
|
|
47
|
+
logger = LoggerFactory.tool("seo");
|
|
48
|
+
clients = new Map();
|
|
49
|
+
seoClients = new Map();
|
|
50
|
+
contentAnalyzer;
|
|
51
|
+
metaGenerator;
|
|
52
|
+
schemaGenerator;
|
|
53
|
+
cacheManager;
|
|
54
|
+
// Client-dependent components created per request
|
|
55
|
+
// private internalLinkingSuggester: InternalLinkingSuggester;
|
|
56
|
+
// private siteAuditor: SiteAuditor;
|
|
57
|
+
// private bulkOperations: BulkOperations;
|
|
58
|
+
constructor() {
|
|
59
|
+
this.contentAnalyzer = new ContentAnalyzer();
|
|
60
|
+
this.metaGenerator = new MetaGenerator();
|
|
61
|
+
this.schemaGenerator = new SchemaGenerator();
|
|
62
|
+
this.cacheManager = new SEOCacheManager();
|
|
63
|
+
// Note: Client-dependent components will be initialized when needed in handlers
|
|
64
|
+
// this.internalLinkingSuggester - initialized per request
|
|
65
|
+
// this.siteAuditor - initialized per request
|
|
66
|
+
// this.bulkOperations - initialized per request
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Analyzes content for SEO optimization opportunities.
|
|
70
|
+
*
|
|
71
|
+
* Performs comprehensive analysis including:
|
|
72
|
+
* - Readability scoring (Flesch-Kincaid)
|
|
73
|
+
* - Keyword density and distribution
|
|
74
|
+
* - Content structure evaluation
|
|
75
|
+
* - Meta tag optimization suggestions
|
|
76
|
+
*
|
|
77
|
+
* @param params - Analysis parameters including post ID and analysis type
|
|
78
|
+
* @returns Detailed SEO analysis with scores and recommendations
|
|
79
|
+
*/
|
|
80
|
+
async analyzeContent(params) {
|
|
81
|
+
const siteLogger = LoggerFactory.tool("wp_seo_analyze_content", params.site);
|
|
82
|
+
return await siteLogger.time("SEO content analysis", async () => {
|
|
83
|
+
try {
|
|
84
|
+
validateRequired(params, ["postId", "analysisType"]);
|
|
85
|
+
const client = this.getSiteClient(params.site);
|
|
86
|
+
// Check cache first
|
|
87
|
+
const cacheKey = `seo:analyze:${params.site}:${params.postId}:${params.analysisType}`;
|
|
88
|
+
const cached = await this.getCachedResult(cacheKey);
|
|
89
|
+
if (cached) {
|
|
90
|
+
siteLogger.debug("Cache hit for content analysis", { cacheKey });
|
|
91
|
+
return cached;
|
|
92
|
+
}
|
|
93
|
+
// Perform analysis (implementation will be added in analyzers)
|
|
94
|
+
const result = await this.performAnalysis(client, params);
|
|
95
|
+
// Cache the result
|
|
96
|
+
await this.cacheResult(cacheKey, result, 21600); // 6 hours
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
catch (_error) {
|
|
100
|
+
handleToolError(_error, "analyze content", {
|
|
101
|
+
site: params.site,
|
|
102
|
+
postId: params.postId,
|
|
103
|
+
});
|
|
104
|
+
throw _error; // handleToolError will format it properly
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Generates optimized metadata for posts.
|
|
110
|
+
*
|
|
111
|
+
* Creates SEO-friendly metadata including:
|
|
112
|
+
* - Title tags (60 character limit)
|
|
113
|
+
* - Meta descriptions (155-160 characters)
|
|
114
|
+
* - OpenGraph tags
|
|
115
|
+
* - Twitter Card metadata
|
|
116
|
+
*
|
|
117
|
+
* @param params - Generation parameters including content and constraints
|
|
118
|
+
* @returns Generated metadata with safety filters applied
|
|
119
|
+
*/
|
|
120
|
+
async generateMetadata(params) {
|
|
121
|
+
const siteLogger = LoggerFactory.tool("wp_seo_generate_meta", params.site);
|
|
122
|
+
return await siteLogger.time("Generate SEO metadata", async () => {
|
|
123
|
+
try {
|
|
124
|
+
validateRequired(params, ["postId"]);
|
|
125
|
+
const client = this.getSiteClient(params.site);
|
|
126
|
+
// Implementation will be added in generators
|
|
127
|
+
const metadata = await this.createMetadata(client, params);
|
|
128
|
+
return metadata;
|
|
129
|
+
}
|
|
130
|
+
catch (_error) {
|
|
131
|
+
handleToolError(_error, "generate metadata", {
|
|
132
|
+
site: params.site,
|
|
133
|
+
postId: params.postId,
|
|
134
|
+
});
|
|
135
|
+
throw _error;
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Performs bulk metadata updates with progress tracking.
|
|
141
|
+
*
|
|
142
|
+
* Handles large-scale metadata updates with:
|
|
143
|
+
* - Batch processing (10 posts per batch)
|
|
144
|
+
* - Progress event streaming
|
|
145
|
+
* - Retry logic with exponential backoff
|
|
146
|
+
* - Dry-run mode for validation
|
|
147
|
+
*
|
|
148
|
+
* @param params - Bulk operation parameters
|
|
149
|
+
* @returns Operation results with success/failure counts
|
|
150
|
+
*/
|
|
151
|
+
async bulkUpdateMetadata(params) {
|
|
152
|
+
const siteLogger = LoggerFactory.tool("wp_seo_bulk_update", params.site);
|
|
153
|
+
return await siteLogger.time("Bulk metadata update", async () => {
|
|
154
|
+
try {
|
|
155
|
+
validateRequired(params, ["postIds", "updates"]);
|
|
156
|
+
const client = this.getSiteClient(params.site);
|
|
157
|
+
// Implementation will be added
|
|
158
|
+
const result = await this.processBulkUpdate(client, params);
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
catch (_error) {
|
|
162
|
+
handleToolError(_error, "bulk update metadata", {
|
|
163
|
+
site: params.site,
|
|
164
|
+
count: params.postIds?.length,
|
|
165
|
+
});
|
|
166
|
+
throw _error;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Generates structured data schema markup.
|
|
172
|
+
*
|
|
173
|
+
* Creates JSON-LD schema for:
|
|
174
|
+
* - Article, Product, FAQ, HowTo
|
|
175
|
+
* - Organization, Website, BreadcrumbList
|
|
176
|
+
* - Event, Recipe, Course, and more
|
|
177
|
+
*
|
|
178
|
+
* @param params - Schema generation parameters
|
|
179
|
+
* @returns Valid JSON-LD schema markup
|
|
180
|
+
*/
|
|
181
|
+
async generateSchema(params) {
|
|
182
|
+
const siteLogger = LoggerFactory.tool("wp_seo_generate_schema", params.site);
|
|
183
|
+
return await siteLogger.time("Generate schema markup", async () => {
|
|
184
|
+
try {
|
|
185
|
+
validateRequired(params, ["postId", "schemaType"]);
|
|
186
|
+
const client = this.getSiteClient(params.site);
|
|
187
|
+
// Check cache
|
|
188
|
+
const cacheKey = `seo:schema:${params.site}:${params.postId}:${params.schemaType}`;
|
|
189
|
+
const cached = await this.getCachedResult(cacheKey);
|
|
190
|
+
if (cached) {
|
|
191
|
+
return cached;
|
|
192
|
+
}
|
|
193
|
+
// Generate schema (implementation in generators)
|
|
194
|
+
const schema = await this.createSchema(client, params);
|
|
195
|
+
// Cache for 24 hours
|
|
196
|
+
await this.cacheResult(cacheKey, schema, 86400);
|
|
197
|
+
return schema;
|
|
198
|
+
}
|
|
199
|
+
catch (_error) {
|
|
200
|
+
handleToolError(_error, "generate schema", {
|
|
201
|
+
site: params.site,
|
|
202
|
+
postId: params.postId,
|
|
203
|
+
schemaType: params.schemaType,
|
|
204
|
+
});
|
|
205
|
+
throw _error;
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Validates schema markup for correctness.
|
|
211
|
+
*
|
|
212
|
+
* Performs validation using:
|
|
213
|
+
* - Local validation rules
|
|
214
|
+
* - Google Rich Results Test API (optional)
|
|
215
|
+
* - Schema.org specifications
|
|
216
|
+
*
|
|
217
|
+
* @param params - Validation parameters including schema JSON
|
|
218
|
+
* @returns Validation results with errors and warnings
|
|
219
|
+
*/
|
|
220
|
+
async validateSchema(params) {
|
|
221
|
+
const siteLogger = LoggerFactory.tool("wp_seo_validate_schema", params.site);
|
|
222
|
+
return await siteLogger.time("Validate schema markup", async () => {
|
|
223
|
+
try {
|
|
224
|
+
validateRequired(params, ["schema"]);
|
|
225
|
+
// Implementation will be added in validators
|
|
226
|
+
const validation = await this.performSchemaValidation(params);
|
|
227
|
+
return validation;
|
|
228
|
+
}
|
|
229
|
+
catch (_error) {
|
|
230
|
+
handleToolError(_error, "validate schema", {
|
|
231
|
+
site: params.site,
|
|
232
|
+
});
|
|
233
|
+
throw _error;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Suggests internal linking opportunities.
|
|
239
|
+
*
|
|
240
|
+
* Analyzes content to suggest:
|
|
241
|
+
* - Related posts for contextual linking
|
|
242
|
+
* - Anchor text recommendations
|
|
243
|
+
* - Hub-and-spoke content architectures
|
|
244
|
+
* - Topical cluster connections
|
|
245
|
+
*
|
|
246
|
+
* @param params - Linking parameters including post ID
|
|
247
|
+
* @returns Internal linking suggestions with confidence scores
|
|
248
|
+
*/
|
|
249
|
+
async suggestInternalLinks(params) {
|
|
250
|
+
const siteLogger = LoggerFactory.tool("wp_seo_internal_linking", params.site);
|
|
251
|
+
return await siteLogger.time("Suggest internal links", async () => {
|
|
252
|
+
try {
|
|
253
|
+
validateRequired(params, ["postId"]);
|
|
254
|
+
const client = this.getSiteClient(params.site);
|
|
255
|
+
// Implementation will be added in optimizers
|
|
256
|
+
const suggestions = await this.findLinkingOpportunities(client, params);
|
|
257
|
+
return suggestions;
|
|
258
|
+
}
|
|
259
|
+
catch (_error) {
|
|
260
|
+
handleToolError(_error, "suggest internal links", {
|
|
261
|
+
site: params.site,
|
|
262
|
+
postId: params.postId,
|
|
263
|
+
});
|
|
264
|
+
throw _error;
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Performs comprehensive site SEO audit.
|
|
270
|
+
*
|
|
271
|
+
* Audits include:
|
|
272
|
+
* - Technical SEO issues
|
|
273
|
+
* - Content quality analysis
|
|
274
|
+
* - Core Web Vitals assessment
|
|
275
|
+
* - Mobile usability checks
|
|
276
|
+
* - Structured data validation
|
|
277
|
+
*
|
|
278
|
+
* @param params - Audit parameters including scope and depth
|
|
279
|
+
* @returns Detailed audit results with prioritized recommendations
|
|
280
|
+
*/
|
|
281
|
+
async performSiteAudit(params) {
|
|
282
|
+
const siteLogger = LoggerFactory.tool("wp_seo_site_audit", params.site);
|
|
283
|
+
return await siteLogger.time("Perform site audit", async () => {
|
|
284
|
+
try {
|
|
285
|
+
const client = this.getSiteClient(params.site);
|
|
286
|
+
// Cache key for audit results (1 hour TTL)
|
|
287
|
+
const cacheKey = `seo:audit:${params.site}:${params.auditType || "full"}`;
|
|
288
|
+
const cached = await this.getCachedResult(cacheKey);
|
|
289
|
+
if (cached && !params.force) {
|
|
290
|
+
return cached;
|
|
291
|
+
}
|
|
292
|
+
// Perform audit (implementation will be added)
|
|
293
|
+
const audit = await this.executeSiteAudit(client, params);
|
|
294
|
+
// Cache for 1 hour
|
|
295
|
+
await this.cacheResult(cacheKey, audit, 3600);
|
|
296
|
+
return audit;
|
|
297
|
+
}
|
|
298
|
+
catch (_error) {
|
|
299
|
+
handleToolError(_error, "perform site audit", {
|
|
300
|
+
site: params.site,
|
|
301
|
+
auditType: params.auditType,
|
|
302
|
+
});
|
|
303
|
+
throw _error;
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Retrieves all SEO tool definitions for MCP registration.
|
|
309
|
+
*
|
|
310
|
+
* @returns Array of SEO tool definitions with handlers
|
|
311
|
+
*/
|
|
312
|
+
getTools() {
|
|
313
|
+
return seoToolDefinitions.map((toolDef) => ({
|
|
314
|
+
...toolDef,
|
|
315
|
+
handler: this.getHandlerForTool(toolDef.name),
|
|
316
|
+
}));
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Maps tool names to their corresponding handler methods.
|
|
320
|
+
*
|
|
321
|
+
* @param toolName - Name of the tool
|
|
322
|
+
* @returns Handler function for the tool
|
|
323
|
+
* @private
|
|
324
|
+
*/
|
|
325
|
+
getHandlerForTool(toolName) {
|
|
326
|
+
const handlers = {
|
|
327
|
+
wp_seo_analyze_content: handleAnalyzeContent,
|
|
328
|
+
wp_seo_generate_metadata: handleGenerateMetadata,
|
|
329
|
+
wp_seo_bulk_update_metadata: handleBulkUpdateMetadata,
|
|
330
|
+
wp_seo_generate_schema: handleGenerateSchema,
|
|
331
|
+
wp_seo_validate_schema: handleValidateSchema,
|
|
332
|
+
wp_seo_suggest_internal_links: handleSuggestInternalLinks,
|
|
333
|
+
wp_seo_site_audit: handlePerformSiteAudit,
|
|
334
|
+
wp_seo_track_serp: handleTrackSERPPositions,
|
|
335
|
+
wp_seo_keyword_research: handleKeywordResearch,
|
|
336
|
+
wp_seo_test_integration: handleTestSEOIntegration,
|
|
337
|
+
wp_seo_get_live_data: handleGetLiveSEOData,
|
|
338
|
+
};
|
|
339
|
+
return (handlers[toolName] ||
|
|
340
|
+
(() => {
|
|
341
|
+
throw new Error(`Unknown SEO tool: ${toolName}`);
|
|
342
|
+
}));
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Gets or creates a WordPress client for the specified site.
|
|
346
|
+
*
|
|
347
|
+
* @param site - Site identifier
|
|
348
|
+
* @returns WordPress client instance
|
|
349
|
+
* @private
|
|
350
|
+
*/
|
|
351
|
+
getSiteClient(site) {
|
|
352
|
+
const siteId = site || "default";
|
|
353
|
+
if (!this.clients.has(siteId)) {
|
|
354
|
+
// Create new client for site (implementation depends on multi-site config)
|
|
355
|
+
const client = new WordPressClient();
|
|
356
|
+
this.clients.set(siteId, client);
|
|
357
|
+
}
|
|
358
|
+
return this.clients.get(siteId);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Get SEO-enhanced WordPress client for a specific site
|
|
362
|
+
*/
|
|
363
|
+
async getSEOClient(site) {
|
|
364
|
+
const siteId = site || "default";
|
|
365
|
+
if (!this.seoClients.has(siteId)) {
|
|
366
|
+
// Get base client config and create SEO client
|
|
367
|
+
const baseClient = this.getSiteClient(site);
|
|
368
|
+
const seoClient = new SEOWordPressClient(baseClient.config);
|
|
369
|
+
// Initialize SEO capabilities
|
|
370
|
+
await seoClient.initializeSEO();
|
|
371
|
+
this.seoClients.set(siteId, seoClient);
|
|
372
|
+
}
|
|
373
|
+
return this.seoClients.get(siteId);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Retrieves cached result if available.
|
|
377
|
+
*
|
|
378
|
+
* @param key - Cache key
|
|
379
|
+
* @returns Cached result or null
|
|
380
|
+
* @private
|
|
381
|
+
*/
|
|
382
|
+
async getCachedResult(key) {
|
|
383
|
+
return this.cacheManager.get(key);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Caches a result with specified TTL.
|
|
387
|
+
*
|
|
388
|
+
* @param key - Cache key
|
|
389
|
+
* @param result - Result to cache
|
|
390
|
+
* @param ttl - Time to live in seconds
|
|
391
|
+
* @private
|
|
392
|
+
*/
|
|
393
|
+
async cacheResult(key, result, ttl) {
|
|
394
|
+
await this.cacheManager.set(key, result, ttl);
|
|
395
|
+
}
|
|
396
|
+
// Implementation methods
|
|
397
|
+
async performAnalysis(client, params) {
|
|
398
|
+
// Fetch the post data
|
|
399
|
+
const post = await client.getPost(params.postId);
|
|
400
|
+
// Perform content analysis
|
|
401
|
+
return await this.contentAnalyzer.analyzePost(post, params);
|
|
402
|
+
}
|
|
403
|
+
async createMetadata(client, params) {
|
|
404
|
+
// Fetch the post data
|
|
405
|
+
const post = await client.getPost(params.postId);
|
|
406
|
+
// Check cache first
|
|
407
|
+
const cacheKey = `seo:metadata:${params.site}:${params.postId}`;
|
|
408
|
+
const cached = await this.getCachedResult(cacheKey);
|
|
409
|
+
if (cached) {
|
|
410
|
+
this.logger.debug("Cache hit for metadata generation", { cacheKey });
|
|
411
|
+
return cached;
|
|
412
|
+
}
|
|
413
|
+
// Generate metadata
|
|
414
|
+
const metadata = await this.metaGenerator.generateMetadata(post, params, {
|
|
415
|
+
includeKeywords: Boolean(params.focusKeywords?.length),
|
|
416
|
+
brandVoice: "professional", // Could be configurable
|
|
417
|
+
includeCallToAction: true,
|
|
418
|
+
preserveExisting: false,
|
|
419
|
+
});
|
|
420
|
+
// Cache for 2 hours
|
|
421
|
+
await this.cacheResult(cacheKey, metadata, 7200);
|
|
422
|
+
return metadata;
|
|
423
|
+
}
|
|
424
|
+
async processBulkUpdate(client, params) {
|
|
425
|
+
// Initialize BulkOperations for the specific client if needed
|
|
426
|
+
const bulkOps = new BulkOperations(client, this.cacheManager, {
|
|
427
|
+
batchSize: 10,
|
|
428
|
+
maxRetries: 3,
|
|
429
|
+
enableProgress: true,
|
|
430
|
+
});
|
|
431
|
+
// Set up progress callback for logging
|
|
432
|
+
const progressCallback = (progress) => {
|
|
433
|
+
this.logger.info("Bulk operation progress", {
|
|
434
|
+
progress: `${progress.processed}/${progress.total}`,
|
|
435
|
+
success: progress.completed,
|
|
436
|
+
failed: progress.failed,
|
|
437
|
+
currentBatch: `${progress.currentBatch}/${progress.totalBatches}`,
|
|
438
|
+
eta: progress.eta,
|
|
439
|
+
});
|
|
440
|
+
};
|
|
441
|
+
// Execute bulk metadata update
|
|
442
|
+
return await bulkOps.bulkUpdateMetadata(params, progressCallback);
|
|
443
|
+
}
|
|
444
|
+
async createSchema(client, params) {
|
|
445
|
+
// Fetch the post data
|
|
446
|
+
const post = await client.getPost(params.postId);
|
|
447
|
+
if (!post) {
|
|
448
|
+
throw new Error(`Post ${params.postId} not found`);
|
|
449
|
+
}
|
|
450
|
+
// Generate schema markup
|
|
451
|
+
const options = {
|
|
452
|
+
includeAuthor: true,
|
|
453
|
+
includeOrganization: true,
|
|
454
|
+
includeBreadcrumbs: params.schemaType === "BreadcrumbList",
|
|
455
|
+
includeImages: true,
|
|
456
|
+
siteConfig: {
|
|
457
|
+
name: "WordPress Site", // This could be configurable
|
|
458
|
+
url: "https://example.com", // This could come from site settings
|
|
459
|
+
description: "WordPress site with SEO optimization",
|
|
460
|
+
},
|
|
461
|
+
customProperties: {
|
|
462
|
+
...(params.focusKeywords && { keywords: params.focusKeywords }),
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
return await this.schemaGenerator.generateSchema(post, params, options);
|
|
466
|
+
}
|
|
467
|
+
async performSchemaValidation(params) {
|
|
468
|
+
if (!params.schema) {
|
|
469
|
+
throw new Error("Schema markup is required for validation");
|
|
470
|
+
}
|
|
471
|
+
// Basic validation using the SchemaGenerator's validation method
|
|
472
|
+
const validation = this.schemaGenerator.validateSchema(params.schema);
|
|
473
|
+
return {
|
|
474
|
+
valid: validation.valid,
|
|
475
|
+
errors: validation.errors,
|
|
476
|
+
warnings: [], // Could add warnings for best practices
|
|
477
|
+
schemaType: params.schema["@type"],
|
|
478
|
+
validatedAt: new Date().toISOString(),
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
async findLinkingOpportunities(client, params) {
|
|
482
|
+
// Fetch the source post
|
|
483
|
+
const post = await client.getPost(params.postId);
|
|
484
|
+
if (!post) {
|
|
485
|
+
throw new Error(`Post ${params.postId} not found`);
|
|
486
|
+
}
|
|
487
|
+
// Initialize internal linking suggester for the specific client
|
|
488
|
+
const linkingSuggester = new InternalLinkingSuggester(client, {
|
|
489
|
+
maxSuggestions: params.maxSuggestions || 10,
|
|
490
|
+
minRelevanceScore: params.minimumRelevance || 30,
|
|
491
|
+
maxLinksPerPost: 5,
|
|
492
|
+
useSemanticAnalysis: true,
|
|
493
|
+
enableContextualPlacement: true,
|
|
494
|
+
});
|
|
495
|
+
// Generate internal linking suggestions
|
|
496
|
+
const suggestions = await linkingSuggester.generateSuggestions(post, params);
|
|
497
|
+
return {
|
|
498
|
+
postId: params.postId,
|
|
499
|
+
postTitle: post.title?.rendered || "Untitled",
|
|
500
|
+
suggestions,
|
|
501
|
+
totalSuggestions: suggestions.length,
|
|
502
|
+
averageRelevance: suggestions.length > 0
|
|
503
|
+
? (suggestions.reduce((sum, s) => sum + s.relevance, 0) / suggestions.length).toFixed(1)
|
|
504
|
+
: 0,
|
|
505
|
+
generatedAt: new Date().toISOString(),
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Test SEO plugin integration and WordPress API connectivity
|
|
510
|
+
*/
|
|
511
|
+
async testSEOIntegration(params) {
|
|
512
|
+
const siteLogger = LoggerFactory.tool("wp_seo_test_integration", params.site);
|
|
513
|
+
return await siteLogger.time("Test SEO integration", async () => {
|
|
514
|
+
try {
|
|
515
|
+
const seoClient = await this.getSEOClient(params.site);
|
|
516
|
+
// Test the integration
|
|
517
|
+
const integrationTest = await seoClient.testSEOIntegration();
|
|
518
|
+
// Get some sample SEO data
|
|
519
|
+
let sampleSEOData = null;
|
|
520
|
+
if (integrationTest.canReadMetadata && integrationTest.samplePostsWithSEO > 0) {
|
|
521
|
+
try {
|
|
522
|
+
const posts = await seoClient.getPosts({ per_page: 1, status: ["publish"] });
|
|
523
|
+
if (posts && posts.length > 0) {
|
|
524
|
+
sampleSEOData = await seoClient.getSEOMetadata(posts[0].id);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
catch (_error) {
|
|
528
|
+
// Sample data fetch failed, but that's okay
|
|
529
|
+
this.logger.debug("Failed to fetch sample SEO data", { _error: _error });
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
const result = {
|
|
533
|
+
integrationTest,
|
|
534
|
+
sampleSEOData,
|
|
535
|
+
recommendations: this.generateIntegrationRecommendations(integrationTest),
|
|
536
|
+
testedAt: new Date().toISOString(),
|
|
537
|
+
};
|
|
538
|
+
siteLogger.info("SEO integration test completed", {
|
|
539
|
+
plugin: integrationTest.pluginDetected,
|
|
540
|
+
canRead: integrationTest.canReadMetadata,
|
|
541
|
+
canWrite: integrationTest.canWriteMetadata,
|
|
542
|
+
postsWithSEO: integrationTest.samplePostsWithSEO,
|
|
543
|
+
});
|
|
544
|
+
return result;
|
|
545
|
+
}
|
|
546
|
+
catch (_error) {
|
|
547
|
+
handleToolError(_error, "test SEO integration", {
|
|
548
|
+
site: params.site,
|
|
549
|
+
});
|
|
550
|
+
throw _error;
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Get live SEO data for multiple posts
|
|
556
|
+
*/
|
|
557
|
+
async getLiveSEOData(params) {
|
|
558
|
+
const siteLogger = LoggerFactory.tool("wp_seo_get_live_data", params.site);
|
|
559
|
+
return await siteLogger.time("Get live SEO data", async () => {
|
|
560
|
+
try {
|
|
561
|
+
const seoClient = await this.getSEOClient(params.site);
|
|
562
|
+
// Get all posts with SEO data
|
|
563
|
+
const postsWithSEO = await seoClient.getAllPostsWithSEO({
|
|
564
|
+
maxPosts: params.maxPosts || 20,
|
|
565
|
+
includePages: true,
|
|
566
|
+
});
|
|
567
|
+
// Analyze the SEO data
|
|
568
|
+
const analysis = this.analyzeLiveSEOData(postsWithSEO);
|
|
569
|
+
const result = {
|
|
570
|
+
totalContent: postsWithSEO.length,
|
|
571
|
+
contentWithSEO: postsWithSEO.filter((p) => p.seoData).length,
|
|
572
|
+
analysis,
|
|
573
|
+
posts: postsWithSEO.map((post) => ({
|
|
574
|
+
id: post.id,
|
|
575
|
+
title: post.title?.rendered,
|
|
576
|
+
type: post.type,
|
|
577
|
+
url: post.link,
|
|
578
|
+
seoData: post.seoData
|
|
579
|
+
? {
|
|
580
|
+
hasTitle: !!post.seoData.title,
|
|
581
|
+
hasDescription: !!post.seoData.description,
|
|
582
|
+
hasFocusKeyword: !!post.seoData.focusKeyword,
|
|
583
|
+
plugin: post.seoData.plugin,
|
|
584
|
+
lastModified: post.seoData.lastModified,
|
|
585
|
+
}
|
|
586
|
+
: null,
|
|
587
|
+
})),
|
|
588
|
+
retrievedAt: new Date().toISOString(),
|
|
589
|
+
};
|
|
590
|
+
siteLogger.info("Live SEO data retrieved", {
|
|
591
|
+
totalContent: result.totalContent,
|
|
592
|
+
withSEO: result.contentWithSEO,
|
|
593
|
+
plugin: analysis.detectedPlugin,
|
|
594
|
+
});
|
|
595
|
+
return result;
|
|
596
|
+
}
|
|
597
|
+
catch (_error) {
|
|
598
|
+
handleToolError(_error, "get live SEO data", {
|
|
599
|
+
site: params.site,
|
|
600
|
+
maxPosts: params.maxPosts,
|
|
601
|
+
});
|
|
602
|
+
throw _error;
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
async executeSiteAudit(client, params) {
|
|
607
|
+
// Initialize site auditor for the specific client
|
|
608
|
+
const siteAuditor = new SiteAuditor(client, {
|
|
609
|
+
includeTechnical: params.includeTechnical !== false,
|
|
610
|
+
includeContent: params.includeContent !== false,
|
|
611
|
+
includeArchitecture: params.includeArchitecture !== false,
|
|
612
|
+
includePerformance: params.includePerformance !== false,
|
|
613
|
+
includeAccessibility: params.includeAccessibility || false,
|
|
614
|
+
maxPagesForContentAudit: params.maxPages || 50,
|
|
615
|
+
minSeverityLevel: params.minSeverity || "medium",
|
|
616
|
+
includeRecommendations: params.includeRecommendations !== false,
|
|
617
|
+
});
|
|
618
|
+
// Perform comprehensive site audit
|
|
619
|
+
return await siteAuditor.performSiteAudit(params);
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Generate integration recommendations based on test results
|
|
623
|
+
*/
|
|
624
|
+
generateIntegrationRecommendations(testResult) {
|
|
625
|
+
const recommendations = [];
|
|
626
|
+
if (testResult.pluginDetected === "none") {
|
|
627
|
+
recommendations.push("Consider installing a WordPress SEO plugin like Yoast SEO or RankMath for better SEO metadata management");
|
|
628
|
+
}
|
|
629
|
+
if (!testResult.canReadMetadata) {
|
|
630
|
+
recommendations.push("SEO metadata reading failed. Check WordPress REST API permissions and ensure the detected SEO plugin exposes metadata via REST API");
|
|
631
|
+
}
|
|
632
|
+
if (!testResult.canWriteMetadata) {
|
|
633
|
+
recommendations.push("SEO metadata writing failed. Verify user permissions for editing posts and pages via WordPress REST API");
|
|
634
|
+
}
|
|
635
|
+
if (testResult.samplePostsWithSEO === 0) {
|
|
636
|
+
recommendations.push("No SEO metadata found on sample posts. Consider adding SEO titles and descriptions to your content");
|
|
637
|
+
}
|
|
638
|
+
else if (testResult.samplePostsWithSEO < 3) {
|
|
639
|
+
recommendations.push("Limited SEO metadata detected. Consider optimizing more posts with SEO titles, descriptions, and focus keywords");
|
|
640
|
+
}
|
|
641
|
+
if (testResult.errors && testResult.errors.length > 0) {
|
|
642
|
+
recommendations.push("Integration errors detected. Review error details and check WordPress configuration, plugin settings, and REST API accessibility");
|
|
643
|
+
}
|
|
644
|
+
if (recommendations.length === 0) {
|
|
645
|
+
recommendations.push("SEO integration is working well! All tests passed successfully.");
|
|
646
|
+
}
|
|
647
|
+
return recommendations;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Analyze live SEO data for insights
|
|
651
|
+
*/
|
|
652
|
+
analyzeLiveSEOData(posts) {
|
|
653
|
+
const analysis = {
|
|
654
|
+
detectedPlugin: "none",
|
|
655
|
+
totalPosts: posts.length,
|
|
656
|
+
postsWithSEO: 0,
|
|
657
|
+
postsWithTitles: 0,
|
|
658
|
+
postsWithDescriptions: 0,
|
|
659
|
+
postsWithFocusKeywords: 0,
|
|
660
|
+
averageMetadataCompleteness: 0,
|
|
661
|
+
recommendations: [],
|
|
662
|
+
};
|
|
663
|
+
const pluginCounts = { yoast: 0, rankmath: 0, seopress: 0, none: 0 };
|
|
664
|
+
for (const post of posts) {
|
|
665
|
+
if (post.seoData) {
|
|
666
|
+
analysis.postsWithSEO++;
|
|
667
|
+
// Count plugin usage
|
|
668
|
+
pluginCounts[post.seoData.plugin]++;
|
|
669
|
+
// Count metadata presence
|
|
670
|
+
if (post.seoData.title)
|
|
671
|
+
analysis.postsWithTitles++;
|
|
672
|
+
if (post.seoData.description)
|
|
673
|
+
analysis.postsWithDescriptions++;
|
|
674
|
+
if (post.seoData.focusKeyword)
|
|
675
|
+
analysis.postsWithFocusKeywords++;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
// Determine most common plugin
|
|
679
|
+
const mostUsedPlugin = Object.entries(pluginCounts).reduce((a, b) => pluginCounts[a[0]] > pluginCounts[b[0]] ? a : b);
|
|
680
|
+
analysis.detectedPlugin = mostUsedPlugin[0];
|
|
681
|
+
// Calculate metadata completeness
|
|
682
|
+
if (analysis.postsWithSEO > 0) {
|
|
683
|
+
const titleCompleteness = (analysis.postsWithTitles / analysis.postsWithSEO) * 100;
|
|
684
|
+
const descriptionCompleteness = (analysis.postsWithDescriptions / analysis.postsWithSEO) * 100;
|
|
685
|
+
const keywordCompleteness = (analysis.postsWithFocusKeywords / analysis.postsWithSEO) * 100;
|
|
686
|
+
analysis.averageMetadataCompleteness = Math.round((titleCompleteness + descriptionCompleteness + keywordCompleteness) / 3);
|
|
687
|
+
}
|
|
688
|
+
// Generate recommendations
|
|
689
|
+
const seoPercentage = (analysis.postsWithSEO / analysis.totalPosts) * 100;
|
|
690
|
+
if (seoPercentage < 50) {
|
|
691
|
+
analysis.recommendations.push(`Only ${Math.round(seoPercentage)}% of content has SEO metadata. Consider optimizing more posts.`);
|
|
692
|
+
}
|
|
693
|
+
if (analysis.averageMetadataCompleteness < 70) {
|
|
694
|
+
analysis.recommendations.push(`Metadata completeness is ${analysis.averageMetadataCompleteness}%. Focus on adding missing titles, descriptions, and focus keywords.`);
|
|
695
|
+
}
|
|
696
|
+
const titlePercentage = analysis.postsWithSEO > 0 ? (analysis.postsWithTitles / analysis.postsWithSEO) * 100 : 0;
|
|
697
|
+
if (titlePercentage < 80) {
|
|
698
|
+
analysis.recommendations.push(`${Math.round(100 - titlePercentage)}% of SEO-enabled posts lack custom titles. Add SEO titles for better search visibility.`);
|
|
699
|
+
}
|
|
700
|
+
const descPercentage = analysis.postsWithSEO > 0 ? (analysis.postsWithDescriptions / analysis.postsWithSEO) * 100 : 0;
|
|
701
|
+
if (descPercentage < 80) {
|
|
702
|
+
analysis.recommendations.push(`${Math.round(100 - descPercentage)}% of SEO-enabled posts lack meta descriptions. Add descriptions to improve click-through rates.`);
|
|
703
|
+
}
|
|
704
|
+
return analysis;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
export default SEOTools;
|
|
708
|
+
//# sourceMappingURL=SEOTools.js.map
|