mcp-wordpress 1.2.2 → 1.3.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 +210 -182
- package/dist/cache/CacheInvalidation.d.ts +3 -3
- package/dist/cache/CacheInvalidation.d.ts.map +1 -1
- package/dist/cache/CacheInvalidation.js +119 -119
- package/dist/cache/CacheInvalidation.js.map +1 -1
- package/dist/cache/CacheManager.d.ts +5 -0
- package/dist/cache/CacheManager.d.ts.map +1 -1
- package/dist/cache/CacheManager.js +26 -16
- package/dist/cache/CacheManager.js.map +1 -1
- package/dist/cache/HttpCacheWrapper.d.ts +1 -1
- package/dist/cache/HttpCacheWrapper.d.ts.map +1 -1
- package/dist/cache/HttpCacheWrapper.js +29 -29
- package/dist/cache/HttpCacheWrapper.js.map +1 -1
- package/dist/cache/__tests__/CacheInvalidation.test.js +96 -94
- package/dist/cache/__tests__/CacheInvalidation.test.js.map +1 -1
- package/dist/cache/__tests__/CacheManager.test.js +113 -113
- package/dist/cache/__tests__/CacheManager.test.js.map +1 -1
- package/dist/cache/__tests__/CachedWordPressClient.test.js +102 -99
- package/dist/cache/__tests__/CachedWordPressClient.test.js.map +1 -1
- package/dist/cache/__tests__/HttpCacheWrapper.test.js +98 -95
- package/dist/cache/__tests__/HttpCacheWrapper.test.js.map +1 -1
- package/dist/cache/index.d.ts +7 -7
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +4 -4
- package/dist/cache/index.js.map +1 -1
- package/dist/client/CachedWordPressClient.d.ts +4 -4
- package/dist/client/CachedWordPressClient.d.ts.map +1 -1
- package/dist/client/CachedWordPressClient.js +55 -51
- package/dist/client/CachedWordPressClient.js.map +1 -1
- package/dist/client/api.d.ts +10 -10
- package/dist/client/api.js +158 -158
- package/dist/client/api.js.map +1 -1
- package/dist/client/auth.d.ts +2 -2
- package/dist/client/auth.js +72 -72
- package/dist/client/managers/AuthenticationManager.d.ts +2 -2
- package/dist/client/managers/AuthenticationManager.js +46 -46
- package/dist/client/managers/BaseManager.d.ts +1 -1
- package/dist/client/managers/BaseManager.js +9 -9
- package/dist/client/managers/RequestManager.d.ts +5 -3
- package/dist/client/managers/RequestManager.d.ts.map +1 -1
- package/dist/client/managers/RequestManager.js +39 -19
- package/dist/client/managers/RequestManager.js.map +1 -1
- package/dist/client/managers/index.d.ts +3 -3
- package/dist/client/managers/index.js +3 -3
- package/dist/config/ConfigurationSchema.d.ts +2 -2
- package/dist/config/ConfigurationSchema.d.ts.map +1 -1
- package/dist/config/ConfigurationSchema.js +40 -40
- package/dist/config/ConfigurationSchema.js.map +1 -1
- package/dist/config/ServerConfiguration.d.ts +2 -2
- package/dist/config/ServerConfiguration.js +35 -35
- package/dist/config/ServerConfiguration.js.map +1 -1
- package/dist/docs/DocumentationGenerator.d.ts.map +1 -1
- package/dist/docs/DocumentationGenerator.js +296 -255
- package/dist/docs/DocumentationGenerator.js.map +1 -1
- package/dist/docs/MarkdownFormatter.d.ts +1 -1
- package/dist/docs/MarkdownFormatter.d.ts.map +1 -1
- package/dist/docs/MarkdownFormatter.js +60 -51
- package/dist/docs/MarkdownFormatter.js.map +1 -1
- package/dist/docs/index.d.ts +3 -3
- package/dist/docs/index.d.ts.map +1 -1
- package/dist/docs/index.js +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -16
- package/dist/index.js.map +1 -1
- package/dist/mcp-wordpress-1.3.0.tgz +0 -0
- package/dist/performance/MetricsCollector.d.ts +3 -3
- package/dist/performance/MetricsCollector.d.ts.map +1 -1
- package/dist/performance/MetricsCollector.js +33 -27
- package/dist/performance/MetricsCollector.js.map +1 -1
- package/dist/performance/PerformanceAnalytics.d.ts +12 -12
- package/dist/performance/PerformanceAnalytics.d.ts.map +1 -1
- package/dist/performance/PerformanceAnalytics.js +200 -154
- package/dist/performance/PerformanceAnalytics.js.map +1 -1
- package/dist/performance/PerformanceMonitor.d.ts +5 -5
- package/dist/performance/PerformanceMonitor.d.ts.map +1 -1
- package/dist/performance/PerformanceMonitor.js +53 -52
- package/dist/performance/PerformanceMonitor.js.map +1 -1
- package/dist/performance/index.d.ts +6 -6
- package/dist/performance/index.d.ts.map +1 -1
- package/dist/performance/index.js +3 -3
- package/dist/security/InputValidator.d.ts +1 -1
- package/dist/security/InputValidator.d.ts.map +1 -1
- package/dist/security/InputValidator.js +111 -88
- package/dist/security/InputValidator.js.map +1 -1
- package/dist/security/SecurityConfig.d.ts +5 -5
- package/dist/security/SecurityConfig.js +92 -92
- package/dist/security/SecurityConfig.js.map +1 -1
- package/dist/server/ConnectionTester.d.ts +1 -1
- package/dist/server/ConnectionTester.d.ts.map +1 -1
- package/dist/server/ConnectionTester.js +4 -4
- 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 +35 -32
- package/dist/server/ToolRegistry.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +2 -2
- package/dist/tools/BaseToolManager.js +5 -5
- package/dist/tools/auth.d.ts +2 -2
- package/dist/tools/auth.d.ts.map +1 -1
- package/dist/tools/auth.js +32 -31
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/cache.d.ts +1 -1
- package/dist/tools/cache.d.ts.map +1 -1
- package/dist/tools/cache.js +71 -71
- package/dist/tools/cache.js.map +1 -1
- package/dist/tools/comments.d.ts +2 -2
- package/dist/tools/comments.d.ts.map +1 -1
- package/dist/tools/comments.js +79 -79
- package/dist/tools/comments.js.map +1 -1
- package/dist/tools/index.d.ts +10 -10
- package/dist/tools/index.js +10 -10
- package/dist/tools/media.d.ts +2 -2
- package/dist/tools/media.js +80 -80
- package/dist/tools/pages.d.ts +2 -2
- package/dist/tools/pages.d.ts.map +1 -1
- package/dist/tools/pages.js +75 -75
- package/dist/tools/pages.js.map +1 -1
- package/dist/tools/performance.d.ts +1 -1
- package/dist/tools/performance.d.ts.map +1 -1
- package/dist/tools/performance.js +311 -287
- package/dist/tools/performance.js.map +1 -1
- package/dist/tools/posts.d.ts +2 -2
- package/dist/tools/posts.d.ts.map +1 -1
- package/dist/tools/posts.js +94 -94
- package/dist/tools/posts.js.map +1 -1
- package/dist/tools/site.d.ts +2 -2
- package/dist/tools/site.d.ts.map +1 -1
- package/dist/tools/site.js +60 -60
- package/dist/tools/site.js.map +1 -1
- package/dist/tools/taxonomies.d.ts +2 -2
- package/dist/tools/taxonomies.js +89 -89
- package/dist/tools/users.d.ts +2 -2
- package/dist/tools/users.js +68 -68
- package/dist/tools/users.js.map +1 -1
- package/dist/types/client.d.ts +13 -13
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/client.js +12 -12
- package/dist/types/client.js.map +1 -1
- package/dist/types/index.d.ts +19 -19
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -3
- package/dist/types/mcp.d.ts +7 -7
- package/dist/types/wordpress.d.ts +21 -21
- package/dist/types/wordpress.d.ts.map +1 -1
- package/dist/utils/debug.d.ts +2 -2
- package/dist/utils/debug.js +28 -28
- package/dist/utils/error.d.ts.map +1 -1
- package/dist/utils/error.js +13 -13
- package/dist/utils/error.js.map +1 -1
- package/dist/utils/toolWrapper.d.ts.map +1 -1
- package/dist/utils/toolWrapper.js +5 -5
- package/dist/utils/toolWrapper.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +41 -31
- package/dist/utils/validation.js.map +1 -1
- package/docs/CACHING.md +36 -2
- package/docs/DOCKER.md +24 -18
- package/docs/PERFORMANCE_MONITORING.md +49 -1
- package/docs/SECURITY_TESTING.md +30 -1
- package/docs/api/README.md +9 -1
- package/docs/api/summary.json +1 -1
- package/docs/contract-testing.md +24 -3
- package/docs/developer/GITHUB_ACTIONS_SETUP.md +8 -2
- package/docs/developer/MAINTENANCE.md +29 -3
- package/docs/developer/MIGRATION_GUIDE.md +13 -1
- package/docs/developer/NPM_AUTH_SETUP.md +13 -2
- package/docs/developer/REFACTORING.md +31 -1
- package/docs/releases/COMMUNITY_ANNOUNCEMENT_v1.1.2.md +18 -7
- package/docs/releases/RELEASE_NOTES_v1.1.2.md +31 -5
- package/docs/user-guides/DOCKER_SETUP.md +264 -0
- package/docs/user-guides/DTX_SETUP.md +327 -0
- package/docs/user-guides/NPM_SETUP.md +109 -0
- package/docs/user-guides/NPX_SETUP.md +281 -0
- package/docs/wordpress-rest-api-authentication-troubleshooting.md +13 -2
- package/package.json +27 -8
- package/src/cache/CacheInvalidation.ts +140 -132
- package/src/cache/CacheManager.ts +40 -29
- package/src/cache/HttpCacheWrapper.ts +105 -68
- package/src/cache/__tests__/CacheInvalidation.test.ts +123 -118
- package/src/cache/__tests__/CacheManager.test.ts +156 -152
- package/src/cache/__tests__/CachedWordPressClient.test.ts +131 -116
- package/src/cache/__tests__/HttpCacheWrapper.test.ts +118 -115
- package/src/cache/index.ts +13 -13
- package/src/client/CachedWordPressClient.ts +90 -80
- package/src/client/api.ts +205 -205
- package/src/client/auth.ts +80 -80
- package/src/client/managers/AuthenticationManager.ts +61 -61
- package/src/client/managers/BaseManager.ts +11 -11
- package/src/client/managers/RequestManager.ts +79 -47
- package/src/client/managers/index.ts +3 -3
- package/src/config/ConfigurationSchema.ts +44 -44
- package/src/config/ServerConfiguration.ts +39 -39
- package/src/docs/DocumentationGenerator.ts +402 -295
- package/src/docs/MarkdownFormatter.ts +94 -69
- package/src/docs/index.ts +4 -4
- package/src/index.ts +24 -21
- package/src/performance/MetricsCollector.ts +90 -58
- package/src/performance/PerformanceAnalytics.ts +386 -262
- package/src/performance/PerformanceMonitor.ts +152 -118
- package/src/performance/index.ts +9 -9
- package/src/security/InputValidator.ts +148 -91
- package/src/security/SecurityConfig.ts +94 -94
- package/src/server/ConnectionTester.ts +21 -15
- package/src/server/ToolRegistry.ts +64 -51
- package/src/server.ts +2 -2
- package/src/tools/BaseToolManager.ts +6 -6
- package/src/tools/auth.ts +42 -37
- package/src/tools/cache.ts +85 -81
- package/src/tools/comments.ts +93 -91
- package/src/tools/index.ts +10 -10
- package/src/tools/media.ts +89 -89
- package/src/tools/pages.ts +89 -87
- package/src/tools/performance.ts +443 -352
- package/src/tools/posts.ts +109 -107
- package/src/tools/site.ts +86 -77
- package/src/tools/taxonomies.ts +102 -102
- package/src/tools/users.ts +77 -77
- package/src/types/client.ts +157 -60
- package/src/types/index.ts +49 -27
- package/src/types/mcp.ts +15 -15
- package/src/types/wordpress.ts +57 -29
- package/src/utils/debug.ts +37 -37
- package/src/utils/error.ts +47 -25
- package/src/utils/toolWrapper.ts +12 -8
- package/src/utils/validation.ts +116 -65
- package/dist/client/WordPressClient.d.ts +0 -81
- package/dist/client/WordPressClient.d.ts.map +0 -1
- package/dist/client/WordPressClient.js +0 -354
- package/dist/client/WordPressClient.js.map +0 -1
- package/dist/performance/AnomalyDetector.d.ts +0 -63
- package/dist/performance/AnomalyDetector.d.ts.map +0 -1
- package/dist/performance/AnomalyDetector.js +0 -222
- package/dist/performance/AnomalyDetector.js.map +0 -1
- package/dist/performance/BenchmarkAnalyzer.d.ts +0 -67
- package/dist/performance/BenchmarkAnalyzer.d.ts.map +0 -1
- package/dist/performance/BenchmarkAnalyzer.js +0 -301
- package/dist/performance/BenchmarkAnalyzer.js.map +0 -1
- package/dist/performance/TrendAnalyzer.d.ts +0 -69
- package/dist/performance/TrendAnalyzer.d.ts.map +0 -1
- package/dist/performance/TrendAnalyzer.js +0 -203
- package/dist/performance/TrendAnalyzer.js.map +0 -1
- package/dist/tools/BaseToolClass.d.ts +0 -76
- package/dist/tools/BaseToolClass.d.ts.map +0 -1
- package/dist/tools/BaseToolClass.js +0 -104
- package/dist/tools/BaseToolClass.js.map +0 -1
- package/dist/tools/base.d.ts +0 -37
- package/dist/tools/base.d.ts.map +0 -1
- package/dist/tools/base.js +0 -60
- package/dist/tools/base.js.map +0 -1
- package/docs/user-guides/CLAUDE_DESKTOP_SETUP.md +0 -187
|
@@ -19,6 +19,7 @@ This document addresses the common issue where WordPress REST API POST/PUT/DELET
|
|
|
19
19
|
**Most Common Cause:** Apache strips the `Authorization` header by default, particularly affecting write operations.
|
|
20
20
|
|
|
21
21
|
**Solution:** Add to your `.htaccess` file:
|
|
22
|
+
|
|
22
23
|
```apache
|
|
23
24
|
# WordPress REST API - Preserve Authorization Header
|
|
24
25
|
RewriteCond %{HTTP:Authorization} ^(.*)
|
|
@@ -26,6 +27,7 @@ RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
|
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
Alternative approach:
|
|
30
|
+
|
|
29
31
|
```apache
|
|
30
32
|
RewriteEngine On
|
|
31
33
|
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
|
@@ -36,6 +38,7 @@ RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
|
|
36
38
|
**Issue:** WordPress requires HTTPS for application passwords by default, but Docker development environments typically use HTTP.
|
|
37
39
|
|
|
38
40
|
**Solution:** Add to your `docker-compose.yml`:
|
|
41
|
+
|
|
39
42
|
```yaml
|
|
40
43
|
services:
|
|
41
44
|
wordpress:
|
|
@@ -49,6 +52,7 @@ services:
|
|
|
49
52
|
**Issue:** WordPress has multiple places to generate passwords, and using the wrong one causes failures.
|
|
50
53
|
|
|
51
54
|
**Solution:** Generate application passwords from:
|
|
55
|
+
|
|
52
56
|
- ✅ `/wp-admin/profile.php` - User Profile page
|
|
53
57
|
- ❌ NOT from 2FA/Security plugin settings
|
|
54
58
|
|
|
@@ -69,6 +73,8 @@ services:
|
|
|
69
73
|
|
|
70
74
|
## Docker-Specific Solutions
|
|
71
75
|
|
|
76
|
+
📖 **For complete Docker setup**: See [Docker Setup Guide](user-guides/DOCKER_SETUP.md)
|
|
77
|
+
|
|
72
78
|
### Complete Docker Configuration
|
|
73
79
|
|
|
74
80
|
```yaml
|
|
@@ -91,6 +97,7 @@ services:
|
|
|
91
97
|
### WordPress .htaccess Template
|
|
92
98
|
|
|
93
99
|
Create `wp-htaccess.conf`:
|
|
100
|
+
|
|
94
101
|
```apache
|
|
95
102
|
# BEGIN WordPress
|
|
96
103
|
RewriteEngine On
|
|
@@ -122,6 +129,7 @@ Look for `Authorization` header in the request output.
|
|
|
122
129
|
### 2. WordPress Debug Information
|
|
123
130
|
|
|
124
131
|
Add to `wp-config.php`:
|
|
132
|
+
|
|
125
133
|
```php
|
|
126
134
|
define('WP_DEBUG', true);
|
|
127
135
|
define('WP_DEBUG_LOG', true);
|
|
@@ -177,14 +185,17 @@ testAuth();
|
|
|
177
185
|
## Common Security Plugin Issues
|
|
178
186
|
|
|
179
187
|
### Wordfence
|
|
188
|
+
|
|
180
189
|
- Check if REST API is blocked in Wordfence settings
|
|
181
190
|
- Temporarily disable to test
|
|
182
191
|
|
|
183
192
|
### iThemes Security
|
|
193
|
+
|
|
184
194
|
- May block REST API requests
|
|
185
195
|
- Check "WordPress Tweaks" → "Disable REST API"
|
|
186
196
|
|
|
187
197
|
### Jetpack
|
|
198
|
+
|
|
188
199
|
- May interfere with authentication
|
|
189
200
|
- Check Jetpack security settings
|
|
190
201
|
|
|
@@ -211,8 +222,8 @@ testAuth();
|
|
|
211
222
|
If application passwords continue to fail:
|
|
212
223
|
|
|
213
224
|
1. **JWT Authentication Plugin**
|
|
214
|
-
2. **OAuth 2.0 Plugin**
|
|
225
|
+
2. **OAuth 2.0 Plugin**
|
|
215
226
|
3. **Custom nonce-based authentication**
|
|
216
227
|
4. **API Key plugins**
|
|
217
228
|
|
|
218
|
-
Remember: The goal is to achieve the same level of functionality that WP-CLI provides, but through the REST API interface.
|
|
229
|
+
Remember: The goal is to achieve the same level of functionality that WP-CLI provides, but through the REST API interface.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-wordpress",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Comprehensive Model Context Protocol server for WordPress management with 59 tools, performance monitoring, intelligent caching, auto-generated documentation, Docker support, TypeScript, and production-ready authentication",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"ai",
|
|
12
12
|
"assistant"
|
|
13
13
|
],
|
|
14
|
-
"homepage": "https://github.com/
|
|
14
|
+
"homepage": "https://github.com/docdyhr/mcp-wordpress#readme",
|
|
15
15
|
"bugs": {
|
|
16
|
-
"url": "https://github.com/
|
|
16
|
+
"url": "https://github.com/docdyhr/mcp-wordpress/issues"
|
|
17
17
|
},
|
|
18
18
|
"repository": {
|
|
19
19
|
"type": "git",
|
|
20
|
-
"url": "git+https://github.com/
|
|
20
|
+
"url": "git+https://github.com/docdyhr/mcp-wordpress.git"
|
|
21
21
|
},
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"author": "Thomas Dyhr",
|
|
@@ -49,37 +49,51 @@
|
|
|
49
49
|
"docs:serve": "npm run docs:generate && node scripts/serve-docs.js",
|
|
50
50
|
"docs:validate": "npm run docs:generate && node scripts/validate-docs.js",
|
|
51
51
|
"docs:watch": "npm run docs:generate && echo 'Watching for changes...' && npm run docs:serve",
|
|
52
|
+
"dxt:build": "node scripts/build-dxt.js",
|
|
53
|
+
"dxt:clean": "rm -rf dxt-build mcp-wordpress.dxt",
|
|
54
|
+
"dxt:package": "npm run dxt:clean && npm run dxt:build",
|
|
55
|
+
"dxt:validate": "dxt validate mcp-wordpress.dxt",
|
|
52
56
|
"fix:rest-auth": "bash scripts/fix-rest-api-auth.sh",
|
|
57
|
+
"format": "prettier --write *.md docs/**/*.md src/**/*.ts tests/**/*.ts",
|
|
58
|
+
"format:check": "prettier --check *.md docs/**/*.md src/**/*.ts tests/**/*.ts",
|
|
53
59
|
"health": "node scripts/health-check.js",
|
|
54
60
|
"lint": "eslint src/ tests/",
|
|
55
61
|
"lint:fix": "eslint src/ tests/ --fix",
|
|
62
|
+
"lint:md": "markdownlint *.md docs/**/*.md",
|
|
63
|
+
"lint:md:fix": "markdownlint *.md docs/**/*.md --fix",
|
|
56
64
|
"pre-commit": "lint-staged",
|
|
57
65
|
"prepare": "husky",
|
|
58
66
|
"prepublishOnly": "npm run build && npm run check:ignore",
|
|
67
|
+
"release": "semantic-release",
|
|
68
|
+
"release:dry": "semantic-release --dry-run",
|
|
59
69
|
"security:audit": "npm audit --production",
|
|
60
70
|
"security:check": "node scripts/security-check.js",
|
|
61
71
|
"security:fix": "npm audit fix",
|
|
72
|
+
"security:full": "npm run security:scan && npm run test:security && npm run security:test",
|
|
73
|
+
"security:scan": "npm audit --audit-level=low && npm run security:check",
|
|
62
74
|
"security:test": "node scripts/security-test.js",
|
|
63
75
|
"setup": "node bin/setup.js",
|
|
64
76
|
"start": "npm run build && node dist/index.js",
|
|
65
77
|
"status": "node bin/status.js",
|
|
66
78
|
"test": "npm run test:typescript",
|
|
67
79
|
"test:auth": "node scripts/test-auth.js",
|
|
80
|
+
"test:cache": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest tests/cache/ --config=jest.typescript.config.json",
|
|
81
|
+
"test:ci": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest --config=jest.ci.config.json --runInBand",
|
|
68
82
|
"test:config": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest tests/config/ --config=jest.typescript.config.json",
|
|
69
|
-
"test:contracts": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest tests/contracts/ --config=jest.typescript.config.json",
|
|
83
|
+
"test:contracts": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest tests/contracts/ --passWithNoTests --config=jest.typescript.config.json",
|
|
70
84
|
"test:contracts:live": "bash scripts/test-contracts-live.sh",
|
|
71
|
-
"test:coverage": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage --collectCoverageFrom='dist/**/*.js' --coverageThreshold='{\"global\":{\"branches\":
|
|
85
|
+
"test:coverage": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage --collectCoverageFrom='dist/**/*.js' --coverageThreshold='{\"global\":{\"branches\":5,\"functions\":5,\"lines\":8,\"statements\":8}}' --config=jest.typescript.config.json",
|
|
72
86
|
"test:fast": "npm run test:typescript",
|
|
73
87
|
"test:integration": "node scripts/test-integration.js",
|
|
74
88
|
"test:legacy": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest",
|
|
75
89
|
"test:mcp": "node scripts/test-mcp.js",
|
|
90
|
+
"test:multisite": "node scripts/test-multisite-quick.js",
|
|
76
91
|
"test:performance": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest tests/performance/ --config=jest.typescript.config.json",
|
|
77
92
|
"test:property": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest tests/property/ --config=jest.typescript.config.json",
|
|
78
93
|
"test:security": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest tests/security/ --config=jest.typescript.config.json",
|
|
79
94
|
"test:security:penetration": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest tests/security/penetration-tests.test.js --config=jest.typescript.config.json",
|
|
80
95
|
"test:security:validation": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest tests/security/security-validation.test.js --config=jest.typescript.config.json",
|
|
81
96
|
"test:tools": "node scripts/test-all-tools-fixed.js",
|
|
82
|
-
"test:multisite": "node scripts/test-multisite-quick.js",
|
|
83
97
|
"test:typescript": "npm run build && NODE_OPTIONS=\"--experimental-vm-modules\" jest --config=jest.typescript.config.json",
|
|
84
98
|
"test:watch": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --watch --config=jest.typescript.config.json",
|
|
85
99
|
"test:with-env": "bash scripts/start-test-env.sh && npm run test:typescript",
|
|
@@ -110,9 +124,13 @@
|
|
|
110
124
|
"@jest/globals": "^30.0.0",
|
|
111
125
|
"@pact-foundation/pact": "^15.0.1",
|
|
112
126
|
"@pact-foundation/pact-node": "^10.18.0",
|
|
127
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
128
|
+
"@semantic-release/git": "^10.0.1",
|
|
113
129
|
"@types/jest": "^30.0.0",
|
|
114
130
|
"@types/node": "^20.19.1",
|
|
115
131
|
"@typescript-eslint/parser": "^8.35.0",
|
|
132
|
+
"archiver": "^7.0.1",
|
|
133
|
+
"conventional-changelog-conventionalcommits": "^9.0.0",
|
|
116
134
|
"eslint": "^9.29.0",
|
|
117
135
|
"eslint-plugin-jest": "^29.0.1",
|
|
118
136
|
"eslint-plugin-node": "^11.1.0",
|
|
@@ -124,11 +142,12 @@
|
|
|
124
142
|
"nock": "^14.0.5",
|
|
125
143
|
"open": "^9.1.0",
|
|
126
144
|
"prettier": "^3.6.2",
|
|
145
|
+
"semantic-release": "^24.0.0",
|
|
127
146
|
"sort-package-json": "^3.3.1",
|
|
128
147
|
"typescript": "^5.8.3"
|
|
129
148
|
},
|
|
130
149
|
"engines": {
|
|
131
|
-
"node": ">=
|
|
150
|
+
"node": ">=20.8.1"
|
|
132
151
|
},
|
|
133
152
|
"publishConfig": {
|
|
134
153
|
"access": "public"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Implements event-based and pattern-based invalidation
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { HttpCacheWrapper } from
|
|
6
|
+
import { HttpCacheWrapper } from "./HttpCacheWrapper.js";
|
|
7
7
|
|
|
8
8
|
export interface InvalidationRule {
|
|
9
9
|
trigger: string;
|
|
@@ -13,7 +13,7 @@ export interface InvalidationRule {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface InvalidationEvent {
|
|
16
|
-
type:
|
|
16
|
+
type: "create" | "update" | "delete";
|
|
17
17
|
resource: string;
|
|
18
18
|
id?: number | undefined;
|
|
19
19
|
siteId: string;
|
|
@@ -48,7 +48,7 @@ export class CacheInvalidation {
|
|
|
48
48
|
*/
|
|
49
49
|
async trigger(event: InvalidationEvent): Promise<void> {
|
|
50
50
|
this.eventQueue.push(event);
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
if (!this.processing) {
|
|
53
53
|
await this.processQueue();
|
|
54
54
|
}
|
|
@@ -58,16 +58,16 @@ export class CacheInvalidation {
|
|
|
58
58
|
* Invalidate cache for specific resource
|
|
59
59
|
*/
|
|
60
60
|
async invalidateResource(
|
|
61
|
-
resource: string,
|
|
62
|
-
id?: number,
|
|
63
|
-
type:
|
|
61
|
+
resource: string,
|
|
62
|
+
id?: number,
|
|
63
|
+
type: "create" | "update" | "delete" = "update",
|
|
64
64
|
): Promise<void> {
|
|
65
65
|
const event: InvalidationEvent = {
|
|
66
66
|
type,
|
|
67
67
|
resource,
|
|
68
68
|
id,
|
|
69
|
-
siteId: this.httpCache[
|
|
70
|
-
timestamp: Date.now()
|
|
69
|
+
siteId: this.httpCache["siteId"], // Access private property
|
|
70
|
+
timestamp: Date.now(),
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
await this.trigger(event);
|
|
@@ -78,184 +78,184 @@ export class CacheInvalidation {
|
|
|
78
78
|
*/
|
|
79
79
|
private setupDefaultRules(): void {
|
|
80
80
|
// Post invalidation rules
|
|
81
|
-
this.registerRule(
|
|
82
|
-
trigger:
|
|
81
|
+
this.registerRule("posts", {
|
|
82
|
+
trigger: "create",
|
|
83
83
|
patterns: [
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
"posts", // All posts listings
|
|
85
|
+
"posts/\\d+", // Specific post
|
|
86
|
+
"categories", // Category listings (if post has categories)
|
|
87
|
+
"tags", // Tag listings (if post has tags)
|
|
88
|
+
"search", // Search results
|
|
89
89
|
],
|
|
90
90
|
immediate: true,
|
|
91
|
-
cascade: true
|
|
91
|
+
cascade: true,
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
-
this.registerRule(
|
|
95
|
-
trigger:
|
|
94
|
+
this.registerRule("posts", {
|
|
95
|
+
trigger: "update",
|
|
96
96
|
patterns: [
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
"posts/\\d+", // Specific post
|
|
98
|
+
"posts.*", // All posts with parameters
|
|
99
|
+
"search", // Search results
|
|
100
100
|
],
|
|
101
|
-
immediate: true
|
|
101
|
+
immediate: true,
|
|
102
102
|
});
|
|
103
103
|
|
|
104
|
-
this.registerRule(
|
|
105
|
-
trigger:
|
|
104
|
+
this.registerRule("posts", {
|
|
105
|
+
trigger: "delete",
|
|
106
106
|
patterns: [
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
"posts", // All posts listings
|
|
108
|
+
"posts/\\d+", // Specific post
|
|
109
|
+
"categories", // Category counts might change
|
|
110
|
+
"tags", // Tag counts might change
|
|
111
|
+
"search", // Search results
|
|
112
112
|
],
|
|
113
113
|
immediate: true,
|
|
114
|
-
cascade: true
|
|
114
|
+
cascade: true,
|
|
115
115
|
});
|
|
116
116
|
|
|
117
117
|
// Page invalidation rules
|
|
118
|
-
this.registerRule(
|
|
119
|
-
trigger:
|
|
120
|
-
patterns: [
|
|
121
|
-
immediate: true
|
|
118
|
+
this.registerRule("pages", {
|
|
119
|
+
trigger: "create",
|
|
120
|
+
patterns: ["pages", "pages/\\d+"],
|
|
121
|
+
immediate: true,
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
-
this.registerRule(
|
|
125
|
-
trigger:
|
|
126
|
-
patterns: [
|
|
127
|
-
immediate: true
|
|
124
|
+
this.registerRule("pages", {
|
|
125
|
+
trigger: "update",
|
|
126
|
+
patterns: ["pages/\\d+", "pages.*"],
|
|
127
|
+
immediate: true,
|
|
128
128
|
});
|
|
129
129
|
|
|
130
|
-
this.registerRule(
|
|
131
|
-
trigger:
|
|
132
|
-
patterns: [
|
|
133
|
-
immediate: true
|
|
130
|
+
this.registerRule("pages", {
|
|
131
|
+
trigger: "delete",
|
|
132
|
+
patterns: ["pages", "pages/\\d+"],
|
|
133
|
+
immediate: true,
|
|
134
134
|
});
|
|
135
135
|
|
|
136
136
|
// Comment invalidation rules
|
|
137
|
-
this.registerRule(
|
|
138
|
-
trigger:
|
|
137
|
+
this.registerRule("comments", {
|
|
138
|
+
trigger: "create",
|
|
139
139
|
patterns: [
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
"comments",
|
|
141
|
+
"comments.*",
|
|
142
|
+
"posts/\\d+.*", // Parent post cache
|
|
143
143
|
],
|
|
144
|
-
immediate: true
|
|
144
|
+
immediate: true,
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
-
this.registerRule(
|
|
148
|
-
trigger:
|
|
147
|
+
this.registerRule("comments", {
|
|
148
|
+
trigger: "update",
|
|
149
149
|
patterns: [
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
"comments/\\d+",
|
|
151
|
+
"comments.*",
|
|
152
|
+
"posts/\\d+.*", // Parent post cache
|
|
153
153
|
],
|
|
154
|
-
immediate: true
|
|
154
|
+
immediate: true,
|
|
155
155
|
});
|
|
156
156
|
|
|
157
|
-
this.registerRule(
|
|
158
|
-
trigger:
|
|
157
|
+
this.registerRule("comments", {
|
|
158
|
+
trigger: "delete",
|
|
159
159
|
patterns: [
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
"comments",
|
|
161
|
+
"comments/\\d+",
|
|
162
|
+
"posts/\\d+.*", // Parent post cache
|
|
163
163
|
],
|
|
164
|
-
immediate: true
|
|
164
|
+
immediate: true,
|
|
165
165
|
});
|
|
166
166
|
|
|
167
167
|
// Media invalidation rules
|
|
168
|
-
this.registerRule(
|
|
169
|
-
trigger:
|
|
170
|
-
patterns: [
|
|
171
|
-
immediate: true
|
|
168
|
+
this.registerRule("media", {
|
|
169
|
+
trigger: "create",
|
|
170
|
+
patterns: ["media", "media.*"],
|
|
171
|
+
immediate: true,
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
-
this.registerRule(
|
|
175
|
-
trigger:
|
|
176
|
-
patterns: [
|
|
177
|
-
immediate: true
|
|
174
|
+
this.registerRule("media", {
|
|
175
|
+
trigger: "update",
|
|
176
|
+
patterns: ["media/\\d+", "media.*"],
|
|
177
|
+
immediate: true,
|
|
178
178
|
});
|
|
179
179
|
|
|
180
|
-
this.registerRule(
|
|
181
|
-
trigger:
|
|
182
|
-
patterns: [
|
|
183
|
-
immediate: true
|
|
180
|
+
this.registerRule("media", {
|
|
181
|
+
trigger: "delete",
|
|
182
|
+
patterns: ["media", "media/\\d+"],
|
|
183
|
+
immediate: true,
|
|
184
184
|
});
|
|
185
185
|
|
|
186
186
|
// User invalidation rules
|
|
187
|
-
this.registerRule(
|
|
188
|
-
trigger:
|
|
189
|
-
patterns: [
|
|
190
|
-
immediate: true
|
|
187
|
+
this.registerRule("users", {
|
|
188
|
+
trigger: "create",
|
|
189
|
+
patterns: ["users", "users.*"],
|
|
190
|
+
immediate: true,
|
|
191
191
|
});
|
|
192
192
|
|
|
193
|
-
this.registerRule(
|
|
194
|
-
trigger:
|
|
193
|
+
this.registerRule("users", {
|
|
194
|
+
trigger: "update",
|
|
195
195
|
patterns: [
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
"users/\\d+",
|
|
197
|
+
"users.*",
|
|
198
|
+
"users/me", // Current user info
|
|
199
199
|
],
|
|
200
|
-
immediate: true
|
|
200
|
+
immediate: true,
|
|
201
201
|
});
|
|
202
202
|
|
|
203
|
-
this.registerRule(
|
|
204
|
-
trigger:
|
|
205
|
-
patterns: [
|
|
206
|
-
immediate: true
|
|
203
|
+
this.registerRule("users", {
|
|
204
|
+
trigger: "delete",
|
|
205
|
+
patterns: ["users", "users/\\d+"],
|
|
206
|
+
immediate: true,
|
|
207
207
|
});
|
|
208
208
|
|
|
209
209
|
// Category invalidation rules
|
|
210
|
-
this.registerRule(
|
|
211
|
-
trigger:
|
|
212
|
-
patterns: [
|
|
210
|
+
this.registerRule("categories", {
|
|
211
|
+
trigger: "create",
|
|
212
|
+
patterns: ["categories", "categories.*", "posts.*"],
|
|
213
213
|
immediate: true,
|
|
214
|
-
cascade: true
|
|
214
|
+
cascade: true,
|
|
215
215
|
});
|
|
216
216
|
|
|
217
|
-
this.registerRule(
|
|
218
|
-
trigger:
|
|
219
|
-
patterns: [
|
|
217
|
+
this.registerRule("categories", {
|
|
218
|
+
trigger: "update",
|
|
219
|
+
patterns: ["categories/\\d+", "categories.*", "posts.*"],
|
|
220
220
|
immediate: true,
|
|
221
|
-
cascade: true
|
|
221
|
+
cascade: true,
|
|
222
222
|
});
|
|
223
223
|
|
|
224
|
-
this.registerRule(
|
|
225
|
-
trigger:
|
|
226
|
-
patterns: [
|
|
224
|
+
this.registerRule("categories", {
|
|
225
|
+
trigger: "delete",
|
|
226
|
+
patterns: ["categories", "categories/\\d+", "posts.*"],
|
|
227
227
|
immediate: true,
|
|
228
|
-
cascade: true
|
|
228
|
+
cascade: true,
|
|
229
229
|
});
|
|
230
230
|
|
|
231
231
|
// Tag invalidation rules
|
|
232
|
-
this.registerRule(
|
|
233
|
-
trigger:
|
|
234
|
-
patterns: [
|
|
232
|
+
this.registerRule("tags", {
|
|
233
|
+
trigger: "create",
|
|
234
|
+
patterns: ["tags", "tags.*", "posts.*"],
|
|
235
235
|
immediate: true,
|
|
236
|
-
cascade: true
|
|
236
|
+
cascade: true,
|
|
237
237
|
});
|
|
238
238
|
|
|
239
|
-
this.registerRule(
|
|
240
|
-
trigger:
|
|
241
|
-
patterns: [
|
|
239
|
+
this.registerRule("tags", {
|
|
240
|
+
trigger: "update",
|
|
241
|
+
patterns: ["tags/\\d+", "tags.*", "posts.*"],
|
|
242
242
|
immediate: true,
|
|
243
|
-
cascade: true
|
|
243
|
+
cascade: true,
|
|
244
244
|
});
|
|
245
245
|
|
|
246
|
-
this.registerRule(
|
|
247
|
-
trigger:
|
|
248
|
-
patterns: [
|
|
246
|
+
this.registerRule("tags", {
|
|
247
|
+
trigger: "delete",
|
|
248
|
+
patterns: ["tags", "tags/\\d+", "posts.*"],
|
|
249
249
|
immediate: true,
|
|
250
|
-
cascade: true
|
|
250
|
+
cascade: true,
|
|
251
251
|
});
|
|
252
252
|
|
|
253
253
|
// Settings invalidation rules (rarely change)
|
|
254
|
-
this.registerRule(
|
|
255
|
-
trigger:
|
|
256
|
-
patterns: [
|
|
254
|
+
this.registerRule("settings", {
|
|
255
|
+
trigger: "update",
|
|
256
|
+
patterns: ["settings.*"],
|
|
257
257
|
immediate: true,
|
|
258
|
-
cascade: false
|
|
258
|
+
cascade: false,
|
|
259
259
|
});
|
|
260
260
|
}
|
|
261
261
|
|
|
@@ -284,9 +284,9 @@ export class CacheInvalidation {
|
|
|
284
284
|
*/
|
|
285
285
|
private async processEvent(event: InvalidationEvent): Promise<void> {
|
|
286
286
|
const rules = this.invalidationRules.get(event.resource) || [];
|
|
287
|
-
|
|
287
|
+
|
|
288
288
|
for (const rule of rules) {
|
|
289
|
-
if (rule.trigger === event.type || rule.trigger ===
|
|
289
|
+
if (rule.trigger === event.type || rule.trigger === "*") {
|
|
290
290
|
await this.applyInvalidationRule(event, rule);
|
|
291
291
|
}
|
|
292
292
|
}
|
|
@@ -296,22 +296,27 @@ export class CacheInvalidation {
|
|
|
296
296
|
* Apply invalidation rule to cache
|
|
297
297
|
*/
|
|
298
298
|
private async applyInvalidationRule(
|
|
299
|
-
event: InvalidationEvent,
|
|
300
|
-
rule: InvalidationRule
|
|
299
|
+
event: InvalidationEvent,
|
|
300
|
+
rule: InvalidationRule,
|
|
301
301
|
): Promise<void> {
|
|
302
302
|
for (const pattern of rule.patterns) {
|
|
303
303
|
let invalidationPattern = pattern;
|
|
304
|
-
|
|
304
|
+
|
|
305
305
|
// Replace placeholders with actual values
|
|
306
306
|
if (event.id) {
|
|
307
|
-
invalidationPattern = invalidationPattern.replace(
|
|
307
|
+
invalidationPattern = invalidationPattern.replace(
|
|
308
|
+
"\\d+",
|
|
309
|
+
event.id.toString(),
|
|
310
|
+
);
|
|
308
311
|
}
|
|
309
|
-
|
|
312
|
+
|
|
310
313
|
// Invalidate matching cache entries
|
|
311
314
|
const invalidated = this.httpCache.invalidatePattern(invalidationPattern);
|
|
312
|
-
|
|
315
|
+
|
|
313
316
|
if (invalidated > 0) {
|
|
314
|
-
console.log(
|
|
317
|
+
console.log(
|
|
318
|
+
`Invalidated ${invalidated} cache entries for pattern: ${invalidationPattern}`,
|
|
319
|
+
);
|
|
315
320
|
}
|
|
316
321
|
}
|
|
317
322
|
}
|
|
@@ -326,8 +331,11 @@ export class CacheInvalidation {
|
|
|
326
331
|
} {
|
|
327
332
|
return {
|
|
328
333
|
queueSize: this.eventQueue.length,
|
|
329
|
-
rulesCount: Array.from(this.invalidationRules.values()).reduce(
|
|
330
|
-
|
|
334
|
+
rulesCount: Array.from(this.invalidationRules.values()).reduce(
|
|
335
|
+
(acc, rules) => acc + rules.length,
|
|
336
|
+
0,
|
|
337
|
+
),
|
|
338
|
+
processing: this.processing,
|
|
331
339
|
};
|
|
332
340
|
}
|
|
333
341
|
|
|
@@ -358,28 +366,28 @@ export class WordPressCachePatterns {
|
|
|
358
366
|
* Invalidate all content-related caches
|
|
359
367
|
*/
|
|
360
368
|
static invalidateContent(cache: HttpCacheWrapper): number {
|
|
361
|
-
return cache.invalidatePattern(
|
|
369
|
+
return cache.invalidatePattern("(posts|pages|comments|media)");
|
|
362
370
|
}
|
|
363
371
|
|
|
364
372
|
/**
|
|
365
373
|
* Invalidate all taxonomy-related caches
|
|
366
374
|
*/
|
|
367
375
|
static invalidateTaxonomies(cache: HttpCacheWrapper): number {
|
|
368
|
-
return cache.invalidatePattern(
|
|
376
|
+
return cache.invalidatePattern("(categories|tags|taxonomies)");
|
|
369
377
|
}
|
|
370
378
|
|
|
371
379
|
/**
|
|
372
380
|
* Invalidate all user-related caches
|
|
373
381
|
*/
|
|
374
382
|
static invalidateUsers(cache: HttpCacheWrapper): number {
|
|
375
|
-
return cache.invalidatePattern(
|
|
383
|
+
return cache.invalidatePattern("users");
|
|
376
384
|
}
|
|
377
385
|
|
|
378
386
|
/**
|
|
379
387
|
* Invalidate search-related caches
|
|
380
388
|
*/
|
|
381
389
|
static invalidateSearch(cache: HttpCacheWrapper): number {
|
|
382
|
-
return cache.invalidatePattern(
|
|
390
|
+
return cache.invalidatePattern("search");
|
|
383
391
|
}
|
|
384
392
|
|
|
385
393
|
/**
|
|
@@ -402,20 +410,20 @@ export class CacheWarmer {
|
|
|
402
410
|
async warmEssentials(): Promise<void> {
|
|
403
411
|
// Implementation would depend on your specific WordPress client
|
|
404
412
|
// This is a placeholder for the structure
|
|
405
|
-
console.log(
|
|
413
|
+
console.log("Warming essential caches...");
|
|
406
414
|
}
|
|
407
415
|
|
|
408
416
|
/**
|
|
409
417
|
* Warm cache with taxonomy data
|
|
410
418
|
*/
|
|
411
419
|
async warmTaxonomies(): Promise<void> {
|
|
412
|
-
console.log(
|
|
420
|
+
console.log("Warming taxonomy caches...");
|
|
413
421
|
}
|
|
414
422
|
|
|
415
423
|
/**
|
|
416
424
|
* Warm cache with user data
|
|
417
425
|
*/
|
|
418
426
|
async warmUsers(): Promise<void> {
|
|
419
|
-
console.log(
|
|
427
|
+
console.log("Warming user caches...");
|
|
420
428
|
}
|
|
421
429
|
}
|