@mainwp/control 1.0.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/LICENSE +674 -0
- package/README.md +583 -0
- package/bin/_exit.js +12 -0
- package/bin/dev.js +7 -0
- package/bin/run.js +7 -0
- package/dist/chat/chat-engine.d.ts +213 -0
- package/dist/chat/chat-engine.d.ts.map +1 -0
- package/dist/chat/chat-engine.js +636 -0
- package/dist/chat/chat-engine.js.map +1 -0
- package/dist/chat/index.d.ts +10 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +14 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/providers/anthropic.d.ts +52 -0
- package/dist/chat/providers/anthropic.d.ts.map +1 -0
- package/dist/chat/providers/anthropic.js +292 -0
- package/dist/chat/providers/anthropic.js.map +1 -0
- package/dist/chat/providers/gemini.d.ts +52 -0
- package/dist/chat/providers/gemini.d.ts.map +1 -0
- package/dist/chat/providers/gemini.js +284 -0
- package/dist/chat/providers/gemini.js.map +1 -0
- package/dist/chat/providers/index.d.ts +19 -0
- package/dist/chat/providers/index.d.ts.map +1 -0
- package/dist/chat/providers/index.js +23 -0
- package/dist/chat/providers/index.js.map +1 -0
- package/dist/chat/providers/local.d.ts +37 -0
- package/dist/chat/providers/local.d.ts.map +1 -0
- package/dist/chat/providers/local.js +130 -0
- package/dist/chat/providers/local.js.map +1 -0
- package/dist/chat/providers/openai-compatible.d.ts +155 -0
- package/dist/chat/providers/openai-compatible.d.ts.map +1 -0
- package/dist/chat/providers/openai-compatible.js +264 -0
- package/dist/chat/providers/openai-compatible.js.map +1 -0
- package/dist/chat/providers/openai.d.ts +24 -0
- package/dist/chat/providers/openai.d.ts.map +1 -0
- package/dist/chat/providers/openai.js +62 -0
- package/dist/chat/providers/openai.js.map +1 -0
- package/dist/chat/providers/openrouter.d.ts +26 -0
- package/dist/chat/providers/openrouter.d.ts.map +1 -0
- package/dist/chat/providers/openrouter.js +65 -0
- package/dist/chat/providers/openrouter.js.map +1 -0
- package/dist/chat/providers/provider-fetch.d.ts +15 -0
- package/dist/chat/providers/provider-fetch.d.ts.map +1 -0
- package/dist/chat/providers/provider-fetch.js +35 -0
- package/dist/chat/providers/provider-fetch.js.map +1 -0
- package/dist/chat/providers/provider.d.ts +214 -0
- package/dist/chat/providers/provider.d.ts.map +1 -0
- package/dist/chat/providers/provider.js +166 -0
- package/dist/chat/providers/provider.js.map +1 -0
- package/dist/chat/providers/sse-reader.d.ts +21 -0
- package/dist/chat/providers/sse-reader.d.ts.map +1 -0
- package/dist/chat/providers/sse-reader.js +48 -0
- package/dist/chat/providers/sse-reader.js.map +1 -0
- package/dist/chat/system-prompt.d.ts +33 -0
- package/dist/chat/system-prompt.d.ts.map +1 -0
- package/dist/chat/system-prompt.js +166 -0
- package/dist/chat/system-prompt.js.map +1 -0
- package/dist/chat/tool-envelope.d.ts +72 -0
- package/dist/chat/tool-envelope.d.ts.map +1 -0
- package/dist/chat/tool-envelope.js +263 -0
- package/dist/chat/tool-envelope.js.map +1 -0
- package/dist/commands/abilities/info.d.ts +21 -0
- package/dist/commands/abilities/info.d.ts.map +1 -0
- package/dist/commands/abilities/info.js +80 -0
- package/dist/commands/abilities/info.js.map +1 -0
- package/dist/commands/abilities/list.d.ts +19 -0
- package/dist/commands/abilities/list.d.ts.map +1 -0
- package/dist/commands/abilities/list.js +98 -0
- package/dist/commands/abilities/list.js.map +1 -0
- package/dist/commands/abilities/run.d.ts +75 -0
- package/dist/commands/abilities/run.d.ts.map +1 -0
- package/dist/commands/abilities/run.js +468 -0
- package/dist/commands/abilities/run.js.map +1 -0
- package/dist/commands/chat.d.ts +54 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +384 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/config/show.d.ts +54 -0
- package/dist/commands/config/show.d.ts.map +1 -0
- package/dist/commands/config/show.js +324 -0
- package/dist/commands/config/show.js.map +1 -0
- package/dist/commands/doctor.d.ts +77 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +412 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/jobs/watch.d.ts +50 -0
- package/dist/commands/jobs/watch.d.ts.map +1 -0
- package/dist/commands/jobs/watch.js +269 -0
- package/dist/commands/jobs/watch.js.map +1 -0
- package/dist/commands/login.d.ts +25 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +165 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/profile/delete.d.ts +22 -0
- package/dist/commands/profile/delete.d.ts.map +1 -0
- package/dist/commands/profile/delete.js +57 -0
- package/dist/commands/profile/delete.js.map +1 -0
- package/dist/commands/profile/list.d.ts +19 -0
- package/dist/commands/profile/list.d.ts.map +1 -0
- package/dist/commands/profile/list.js +53 -0
- package/dist/commands/profile/list.js.map +1 -0
- package/dist/commands/profile/use.d.ts +22 -0
- package/dist/commands/profile/use.d.ts.map +1 -0
- package/dist/commands/profile/use.js +46 -0
- package/dist/commands/profile/use.js.map +1 -0
- package/dist/config/fs-utils.d.ts +14 -0
- package/dist/config/fs-utils.d.ts.map +1 -0
- package/dist/config/fs-utils.js +31 -0
- package/dist/config/fs-utils.js.map +1 -0
- package/dist/config/keychain.d.ts +53 -0
- package/dist/config/keychain.d.ts.map +1 -0
- package/dist/config/keychain.js +175 -0
- package/dist/config/keychain.js.map +1 -0
- package/dist/config/profile-store.d.ts +85 -0
- package/dist/config/profile-store.d.ts.map +1 -0
- package/dist/config/profile-store.js +228 -0
- package/dist/config/profile-store.js.map +1 -0
- package/dist/config/settings.d.ts +71 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +151 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/core/abilities-executor.d.ts +126 -0
- package/dist/core/abilities-executor.d.ts.map +1 -0
- package/dist/core/abilities-executor.js +264 -0
- package/dist/core/abilities-executor.js.map +1 -0
- package/dist/core/batch-manager.d.ts +113 -0
- package/dist/core/batch-manager.d.ts.map +1 -0
- package/dist/core/batch-manager.js +244 -0
- package/dist/core/batch-manager.js.map +1 -0
- package/dist/core/http-client.d.ts +111 -0
- package/dist/core/http-client.d.ts.map +1 -0
- package/dist/core/http-client.js +329 -0
- package/dist/core/http-client.js.map +1 -0
- package/dist/core/safety-controller.d.ts +114 -0
- package/dist/core/safety-controller.d.ts.map +1 -0
- package/dist/core/safety-controller.js +229 -0
- package/dist/core/safety-controller.js.map +1 -0
- package/dist/hooks/command-not-found.d.ts +12 -0
- package/dist/hooks/command-not-found.d.ts.map +1 -0
- package/dist/hooks/command-not-found.js +58 -0
- package/dist/hooks/command-not-found.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/base-command.d.ts +123 -0
- package/dist/lib/base-command.d.ts.map +1 -0
- package/dist/lib/base-command.js +285 -0
- package/dist/lib/base-command.js.map +1 -0
- package/dist/output/formatter.d.ts +48 -0
- package/dist/output/formatter.d.ts.map +1 -0
- package/dist/output/formatter.js +138 -0
- package/dist/output/formatter.js.map +1 -0
- package/dist/output/json-envelope.d.ts +43 -0
- package/dist/output/json-envelope.d.ts.map +1 -0
- package/dist/output/json-envelope.js +73 -0
- package/dist/output/json-envelope.js.map +1 -0
- package/dist/utils/audit-logger.d.ts +97 -0
- package/dist/utils/audit-logger.d.ts.map +1 -0
- package/dist/utils/audit-logger.js +169 -0
- package/dist/utils/audit-logger.js.map +1 -0
- package/dist/utils/colors.d.ts +29 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/colors.js +36 -0
- package/dist/utils/colors.js.map +1 -0
- package/dist/utils/errors.d.ts +107 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +149 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/exit-codes.d.ts +21 -0
- package/dist/utils/exit-codes.d.ts.map +1 -0
- package/dist/utils/exit-codes.js +20 -0
- package/dist/utils/exit-codes.js.map +1 -0
- package/dist/utils/format.d.ts +64 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +69 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/prompt.d.ts +34 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +132 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/retry.d.ts +59 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +96 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/terminal-sanitizer.d.ts +60 -0
- package/dist/utils/terminal-sanitizer.d.ts.map +1 -0
- package/dist/utils/terminal-sanitizer.js +166 -0
- package/dist/utils/terminal-sanitizer.js.map +1 -0
- package/dist/validation/input-sanitizer.d.ts +76 -0
- package/dist/validation/input-sanitizer.d.ts.map +1 -0
- package/dist/validation/input-sanitizer.js +199 -0
- package/dist/validation/input-sanitizer.js.map +1 -0
- package/dist/validation/schema-validator.d.ts +75 -0
- package/dist/validation/schema-validator.d.ts.map +1 -0
- package/dist/validation/schema-validator.js +147 -0
- package/dist/validation/schema-validator.js.map +1 -0
- package/oclif.manifest.json +857 -0
- package/package.json +101 -0
- package/scripts/completions/README.md +221 -0
- package/scripts/completions/mainwpcontrol.bash +193 -0
- package/scripts/completions/mainwpcontrol.zsh +267 -0
- package/scripts/completions/profile-completer.sh +35 -0
- package/scripts/completions/regenerate.sh +78 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abilities Executor for mainwpcontrol
|
|
3
|
+
*
|
|
4
|
+
* Single execution pathway for all ability calls.
|
|
5
|
+
* INVARIANT: Both commands and chat route through this module.
|
|
6
|
+
*/
|
|
7
|
+
import { createHttpClient } from './http-client.js';
|
|
8
|
+
import { APIError, InputError } from '../utils/errors.js';
|
|
9
|
+
import { getInputSanitizer } from '../validation/input-sanitizer.js';
|
|
10
|
+
/**
|
|
11
|
+
* Abilities Executor class
|
|
12
|
+
*/
|
|
13
|
+
export class AbilitiesExecutor {
|
|
14
|
+
httpClient;
|
|
15
|
+
baseEndpoint = '/wp-json/wp-abilities/v1';
|
|
16
|
+
abilitiesCache = null;
|
|
17
|
+
cacheExpiry = 0;
|
|
18
|
+
cacheTTL = 5 * 60 * 1000; // 5 minutes
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.httpClient = createHttpClient(config);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* List all available abilities
|
|
24
|
+
*/
|
|
25
|
+
async listAbilities() {
|
|
26
|
+
await this.ensureCache();
|
|
27
|
+
// Return only full-name entries (cache also stores short names for lookups)
|
|
28
|
+
return Array.from(this.abilitiesCache?.entries() ?? [])
|
|
29
|
+
.filter(([key, ability]) => key === ability.name)
|
|
30
|
+
.map(([, ability]) => ability);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get a single ability by name
|
|
34
|
+
*/
|
|
35
|
+
async getAbility(name) {
|
|
36
|
+
await this.ensureCache();
|
|
37
|
+
return this.abilitiesCache?.get(this.normalizeName(name));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Execute an ability
|
|
41
|
+
*
|
|
42
|
+
* @param abilityName - The ability name (e.g., "list-sites-v1" or "mainwp/list-sites-v1")
|
|
43
|
+
* @param input - The input parameters
|
|
44
|
+
* @param options - Execution options (dryRun, confirm)
|
|
45
|
+
*/
|
|
46
|
+
async execute(abilityName, input = {}, options) {
|
|
47
|
+
// Defense-in-depth: sanitize input before any processing
|
|
48
|
+
input = getInputSanitizer().sanitize(input);
|
|
49
|
+
const ability = await this.getAbility(abilityName);
|
|
50
|
+
if (!ability) {
|
|
51
|
+
throw new InputError(`Unknown ability: ${abilityName}`, undefined, 'List available abilities with `mainwpcontrol abilities list`');
|
|
52
|
+
}
|
|
53
|
+
// Build the request body
|
|
54
|
+
const body = this.buildRequestBody(input, options);
|
|
55
|
+
// Determine HTTP method based on annotations
|
|
56
|
+
const method = this.getHttpMethod(ability, options);
|
|
57
|
+
// Build the endpoint
|
|
58
|
+
// Ability names contain a namespace slash (e.g. "mainwp/list-sites-v1")
|
|
59
|
+
// which is part of the WordPress REST route — do NOT encode it.
|
|
60
|
+
const endpoint = `${this.baseEndpoint}/abilities/${ability.name}/run`;
|
|
61
|
+
try {
|
|
62
|
+
let response;
|
|
63
|
+
const requestOptions = options?.signal ? { signal: options.signal } : undefined;
|
|
64
|
+
if (method === 'GET') {
|
|
65
|
+
// For GET requests, nest input under input[key] (WordPress REST style).
|
|
66
|
+
// Control flags (dry_run, confirm) stay top-level.
|
|
67
|
+
const queryString = this.buildGetQueryString(input, options);
|
|
68
|
+
const url = queryString ? `${endpoint}?${queryString}` : endpoint;
|
|
69
|
+
response = await this.httpClient.get(url, requestOptions);
|
|
70
|
+
}
|
|
71
|
+
else if (method === 'DELETE') {
|
|
72
|
+
const queryString = this.buildGetQueryString(input, options);
|
|
73
|
+
const url = queryString ? `${endpoint}?${queryString}` : endpoint;
|
|
74
|
+
response = await this.httpClient.delete(url, requestOptions);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// POST with JSON body
|
|
78
|
+
response = await this.httpClient.post(endpoint, body, requestOptions);
|
|
79
|
+
}
|
|
80
|
+
return this.normalizeResponse(response.data);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (error instanceof APIError) {
|
|
84
|
+
const errorObj = {
|
|
85
|
+
code: error.code,
|
|
86
|
+
message: error.message,
|
|
87
|
+
details: error.details,
|
|
88
|
+
};
|
|
89
|
+
if (error.hint) {
|
|
90
|
+
errorObj.hint = error.hint;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
success: false,
|
|
94
|
+
error: errorObj,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get ability categories
|
|
102
|
+
*/
|
|
103
|
+
async getCategories() {
|
|
104
|
+
const abilities = await this.listAbilities();
|
|
105
|
+
const categories = new Set(abilities.map((a) => a.category));
|
|
106
|
+
return Array.from(categories).sort();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* List abilities by category
|
|
110
|
+
*/
|
|
111
|
+
async listByCategory(category) {
|
|
112
|
+
const abilities = await this.listAbilities();
|
|
113
|
+
return abilities.filter((a) => a.category.toLowerCase() === category.toLowerCase());
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Ensure abilities cache is populated
|
|
117
|
+
*/
|
|
118
|
+
async ensureCache() {
|
|
119
|
+
if (this.abilitiesCache && Date.now() < this.cacheExpiry) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
this.abilitiesCache = new Map();
|
|
123
|
+
// Fetch all pages — API returns Ability[] with WP pagination headers.
|
|
124
|
+
let page = 1;
|
|
125
|
+
let totalPages = 1;
|
|
126
|
+
do {
|
|
127
|
+
const response = await this.httpClient.get(`${this.baseEndpoint}/abilities?per_page=100&page=${page}`);
|
|
128
|
+
const abilities = Array.isArray(response.data)
|
|
129
|
+
? response.data
|
|
130
|
+
: response.data['abilities'] ?? [];
|
|
131
|
+
for (const ability of abilities) {
|
|
132
|
+
this.abilitiesCache.set(ability.name, ability);
|
|
133
|
+
const shortName = this.getShortName(ability.name);
|
|
134
|
+
if (shortName !== ability.name) {
|
|
135
|
+
this.abilitiesCache.set(shortName, ability);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Read WP pagination header for total pages
|
|
139
|
+
const wpTotalPages = response.headers?.get?.('x-wp-totalpages');
|
|
140
|
+
if (wpTotalPages) {
|
|
141
|
+
totalPages = parseInt(wpTotalPages, 10) || 1;
|
|
142
|
+
}
|
|
143
|
+
page++;
|
|
144
|
+
} while (page <= totalPages);
|
|
145
|
+
this.cacheExpiry = Date.now() + this.cacheTTL;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Normalize ability name (handle with/without namespace)
|
|
149
|
+
*/
|
|
150
|
+
normalizeName(name) {
|
|
151
|
+
// Remove leading slash if present
|
|
152
|
+
return name.replace(/^\//, '');
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get short name from full ability name
|
|
156
|
+
*/
|
|
157
|
+
getShortName(fullName) {
|
|
158
|
+
const parts = fullName.split('/');
|
|
159
|
+
return parts[parts.length - 1] ?? fullName;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Build request body with execution options.
|
|
163
|
+
* The WP Abilities API expects: { input: { ...userInput, dry_run?, confirm? } }
|
|
164
|
+
*/
|
|
165
|
+
buildRequestBody(input, options) {
|
|
166
|
+
const merged = { ...input };
|
|
167
|
+
// SECURITY: Strip control flags from user/LLM-provided input.
|
|
168
|
+
// These are set exclusively from execution options (CLI flags or safety flow).
|
|
169
|
+
delete merged['dry_run'];
|
|
170
|
+
delete merged['confirm'];
|
|
171
|
+
delete merged['user_confirmed'];
|
|
172
|
+
if (options?.dryRun) {
|
|
173
|
+
merged['dry_run'] = true;
|
|
174
|
+
}
|
|
175
|
+
if (options?.confirm) {
|
|
176
|
+
merged['confirm'] = true;
|
|
177
|
+
merged['user_confirmed'] = true;
|
|
178
|
+
}
|
|
179
|
+
return { input: merged };
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Determine HTTP method based on ability annotations
|
|
183
|
+
*/
|
|
184
|
+
getHttpMethod(ability, _options) {
|
|
185
|
+
const annotations = ability.meta?.annotations;
|
|
186
|
+
// If readonly, use GET
|
|
187
|
+
if (annotations?.readonly) {
|
|
188
|
+
return 'GET';
|
|
189
|
+
}
|
|
190
|
+
// If destructive and idempotent, use DELETE
|
|
191
|
+
if (annotations?.destructive && annotations?.idempotent) {
|
|
192
|
+
return 'DELETE';
|
|
193
|
+
}
|
|
194
|
+
// Default to POST for write operations
|
|
195
|
+
return 'POST';
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Build query string for GET/DELETE requests with WordPress-style nesting.
|
|
199
|
+
* User input goes under input[key]=value; control flags stay top-level.
|
|
200
|
+
*/
|
|
201
|
+
buildGetQueryString(input, options) {
|
|
202
|
+
const parts = [];
|
|
203
|
+
// SECURITY: Control flags managed exclusively by execution options
|
|
204
|
+
const controlFlags = ['dry_run', 'confirm', 'user_confirmed'];
|
|
205
|
+
// All params go under input[key] — the API treats input as a single object.
|
|
206
|
+
for (const [key, value] of Object.entries(input)) {
|
|
207
|
+
if (value === undefined || value === null)
|
|
208
|
+
continue;
|
|
209
|
+
if (controlFlags.includes(key))
|
|
210
|
+
continue;
|
|
211
|
+
const ek = encodeURIComponent(key);
|
|
212
|
+
if (Array.isArray(value)) {
|
|
213
|
+
// WordPress-style: input[key][0]=v0&input[key][1]=v1
|
|
214
|
+
value.forEach((v, i) => {
|
|
215
|
+
parts.push(`input[${ek}][${i}]=${encodeURIComponent(String(v))}`);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
else if (typeof value === 'object') {
|
|
219
|
+
parts.push(`input[${ek}]=${encodeURIComponent(JSON.stringify(value))}`);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
parts.push(`input[${ek}]=${encodeURIComponent(String(value))}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (options?.dryRun)
|
|
226
|
+
parts.push('input[dry_run]=true');
|
|
227
|
+
if (options?.confirm) {
|
|
228
|
+
parts.push('input[confirm]=true');
|
|
229
|
+
parts.push('input[user_confirmed]=true');
|
|
230
|
+
}
|
|
231
|
+
return parts.join('&');
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Normalize API response to ExecutionResult
|
|
235
|
+
*/
|
|
236
|
+
normalizeResponse(data) {
|
|
237
|
+
// If already in expected format, return as-is
|
|
238
|
+
if (typeof data === 'object' &&
|
|
239
|
+
data !== null &&
|
|
240
|
+
'success' in data &&
|
|
241
|
+
typeof data['success'] === 'boolean') {
|
|
242
|
+
return data;
|
|
243
|
+
}
|
|
244
|
+
// Wrap raw data in success response
|
|
245
|
+
return {
|
|
246
|
+
success: true,
|
|
247
|
+
data: data,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Clear the abilities cache
|
|
252
|
+
*/
|
|
253
|
+
clearCache() {
|
|
254
|
+
this.abilitiesCache = null;
|
|
255
|
+
this.cacheExpiry = 0;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Create an abilities executor from config
|
|
260
|
+
*/
|
|
261
|
+
export function createAbilitiesExecutor(config) {
|
|
262
|
+
return new AbilitiesExecutor(config);
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=abilities-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abilities-executor.js","sourceRoot":"","sources":["../../src/core/abilities-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch Manager for mainwpcontrol
|
|
3
|
+
*
|
|
4
|
+
* Handles batch operations with polling and resume capabilities.
|
|
5
|
+
* Provides exponential backoff for job status polling.
|
|
6
|
+
*/
|
|
7
|
+
import { type HttpClientConfig } from './http-client.js';
|
|
8
|
+
/**
|
|
9
|
+
* Job status types
|
|
10
|
+
*/
|
|
11
|
+
export type JobStatusType = 'pending' | 'running' | 'completed' | 'failed' | 'partial';
|
|
12
|
+
/**
|
|
13
|
+
* Job status response from API
|
|
14
|
+
*/
|
|
15
|
+
export interface JobStatus {
|
|
16
|
+
/** Job identifier */
|
|
17
|
+
id: string;
|
|
18
|
+
/** Current job status */
|
|
19
|
+
status: JobStatusType;
|
|
20
|
+
/** Progress percentage (0-100) */
|
|
21
|
+
progress?: number | undefined;
|
|
22
|
+
/** Total items to process */
|
|
23
|
+
total?: number | undefined;
|
|
24
|
+
/** Items processed so far */
|
|
25
|
+
processed?: number | undefined;
|
|
26
|
+
/** Partial or complete results */
|
|
27
|
+
results?: unknown[] | undefined;
|
|
28
|
+
/** Errors encountered */
|
|
29
|
+
errors?: Array<{
|
|
30
|
+
item?: unknown | undefined;
|
|
31
|
+
message: string;
|
|
32
|
+
code?: string | undefined;
|
|
33
|
+
}> | undefined;
|
|
34
|
+
/** Job creation timestamp */
|
|
35
|
+
created_at?: string | undefined;
|
|
36
|
+
/** Job completion timestamp */
|
|
37
|
+
completed_at?: string | undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Watch options for job polling
|
|
41
|
+
*/
|
|
42
|
+
export interface WatchOptions {
|
|
43
|
+
/** Maximum total wait time in milliseconds (default: 5 minutes) */
|
|
44
|
+
maxWait?: number | undefined;
|
|
45
|
+
/** Initial poll delay in milliseconds (default: 1000) */
|
|
46
|
+
initialDelay?: number | undefined;
|
|
47
|
+
/** Maximum poll delay in milliseconds (default: 30000) */
|
|
48
|
+
maxDelay?: number | undefined;
|
|
49
|
+
/** Delay multiplier for backoff (default: 2) */
|
|
50
|
+
multiplier?: number | undefined;
|
|
51
|
+
/** Optional abort signal */
|
|
52
|
+
signal?: AbortSignal | undefined;
|
|
53
|
+
/** Callback for progress updates */
|
|
54
|
+
onProgress?: ((status: JobStatus) => void) | undefined;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Watch result
|
|
58
|
+
*/
|
|
59
|
+
export interface WatchResult {
|
|
60
|
+
/** Final job status */
|
|
61
|
+
status: JobStatus;
|
|
62
|
+
/** Whether the operation timed out */
|
|
63
|
+
timedOut: boolean;
|
|
64
|
+
/** Total time spent waiting in milliseconds */
|
|
65
|
+
elapsed: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Batch Manager class
|
|
69
|
+
*/
|
|
70
|
+
export declare class BatchManager {
|
|
71
|
+
private readonly httpClient;
|
|
72
|
+
private readonly baseEndpoint;
|
|
73
|
+
constructor(config: HttpClientConfig);
|
|
74
|
+
/**
|
|
75
|
+
* Watch a batch job status with exponential backoff polling
|
|
76
|
+
*
|
|
77
|
+
* Yields status updates as they're received.
|
|
78
|
+
* Completes when job finishes or times out.
|
|
79
|
+
*/
|
|
80
|
+
watchJob(jobId: string, options?: WatchOptions): AsyncGenerator<JobStatus, WatchResult>;
|
|
81
|
+
/**
|
|
82
|
+
* Resume watching a batch job
|
|
83
|
+
*
|
|
84
|
+
* This is a convenience method that wraps watchJob for resuming
|
|
85
|
+
* a previously started job by its ID.
|
|
86
|
+
*/
|
|
87
|
+
resumeJob(jobId: string, options?: WatchOptions): Promise<WatchResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Get the current status of a batch job
|
|
90
|
+
*/
|
|
91
|
+
getJobStatus(jobId: string, signal?: AbortSignal): Promise<JobStatus>;
|
|
92
|
+
/**
|
|
93
|
+
* Check if a status is terminal (job finished)
|
|
94
|
+
*/
|
|
95
|
+
private isTerminalStatus;
|
|
96
|
+
/**
|
|
97
|
+
* Normalize API response to JobStatus, unwrapping success envelope if present
|
|
98
|
+
*/
|
|
99
|
+
private normalizeJobStatus;
|
|
100
|
+
/**
|
|
101
|
+
* Parse job status string
|
|
102
|
+
*/
|
|
103
|
+
private parseJobStatus;
|
|
104
|
+
/**
|
|
105
|
+
* Parse job errors
|
|
106
|
+
*/
|
|
107
|
+
private parseJobErrors;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Create a batch manager from configuration
|
|
111
|
+
*/
|
|
112
|
+
export declare function createBatchManager(config: HttpClientConfig): BatchManager;
|
|
113
|
+
//# sourceMappingURL=batch-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-manager.d.ts","sourceRoot":"","sources":["../../src/core/batch-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAc,KAAK,gBAAgB,EAAoB,MAAM,kBAAkB,CAAC;AAIvF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,yBAAyB;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;IAChC,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAC3B,CAAC,GAAG,SAAS,CAAC;IACf,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,4BAA4B;IAC5B,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,oCAAoC;IACpC,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACxD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,sCAAsC;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;CACjB;AAYD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA8B;gBAE/C,MAAM,EAAE,gBAAgB;IAIpC;;;;;OAKG;IACI,QAAQ,CACb,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,YAAiB,GACzB,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC;IAmGzC;;;;;OAKG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAc5E;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC;IAY3E;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAmC1B;;OAEG;IACH,OAAO,CAAC,cAAc;IA2BtB;;OAEG;IACH,OAAO,CAAC,cAAc;CAwBvB;AAoBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,YAAY,CAEzE"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch Manager for mainwpcontrol
|
|
3
|
+
*
|
|
4
|
+
* Handles batch operations with polling and resume capabilities.
|
|
5
|
+
* Provides exponential backoff for job status polling.
|
|
6
|
+
*/
|
|
7
|
+
import { createHttpClient } from './http-client.js';
|
|
8
|
+
import { APIError, NetworkError } from '../utils/errors.js';
|
|
9
|
+
import { ExponentialBackoff } from '../utils/retry.js';
|
|
10
|
+
/**
|
|
11
|
+
* Default configuration
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULTS = {
|
|
14
|
+
maxWait: 5 * 60 * 1000, // 5 minutes
|
|
15
|
+
initialDelay: 1000, // 1 second
|
|
16
|
+
maxDelay: 30000, // 30 seconds
|
|
17
|
+
multiplier: 2,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Batch Manager class
|
|
21
|
+
*/
|
|
22
|
+
export class BatchManager {
|
|
23
|
+
httpClient;
|
|
24
|
+
baseEndpoint = '/wp-json/wp-abilities/v1';
|
|
25
|
+
constructor(config) {
|
|
26
|
+
this.httpClient = createHttpClient(config);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Watch a batch job status with exponential backoff polling
|
|
30
|
+
*
|
|
31
|
+
* Yields status updates as they're received.
|
|
32
|
+
* Completes when job finishes or times out.
|
|
33
|
+
*/
|
|
34
|
+
async *watchJob(jobId, options = {}) {
|
|
35
|
+
const maxWait = options.maxWait ?? DEFAULTS.maxWait;
|
|
36
|
+
const startTime = Date.now();
|
|
37
|
+
const backoff = new ExponentialBackoff({
|
|
38
|
+
initialDelay: options.initialDelay ?? DEFAULTS.initialDelay,
|
|
39
|
+
maxDelay: options.maxDelay ?? DEFAULTS.maxDelay,
|
|
40
|
+
multiplier: options.multiplier ?? DEFAULTS.multiplier,
|
|
41
|
+
signal: options.signal,
|
|
42
|
+
});
|
|
43
|
+
let lastStatus;
|
|
44
|
+
let timedOut = false;
|
|
45
|
+
while (true) {
|
|
46
|
+
// Check timeout
|
|
47
|
+
const elapsed = Date.now() - startTime;
|
|
48
|
+
if (elapsed >= maxWait) {
|
|
49
|
+
timedOut = true;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
// Check abort
|
|
53
|
+
if (options.signal?.aborted) {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
// Fetch current status
|
|
57
|
+
try {
|
|
58
|
+
const status = await this.getJobStatus(jobId, options.signal);
|
|
59
|
+
lastStatus = status;
|
|
60
|
+
// Yield the status update
|
|
61
|
+
yield status;
|
|
62
|
+
// Call progress callback if provided
|
|
63
|
+
if (options.onProgress) {
|
|
64
|
+
options.onProgress(status);
|
|
65
|
+
}
|
|
66
|
+
// Check if job is complete
|
|
67
|
+
if (this.isTerminalStatus(status.status)) {
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
// Wait before next poll
|
|
71
|
+
try {
|
|
72
|
+
const shouldContinue = await backoff.wait();
|
|
73
|
+
if (!shouldContinue) {
|
|
74
|
+
// Max retries exceeded or already aborted
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Aborted during wait
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
// For network errors, continue polling
|
|
85
|
+
if (error instanceof NetworkError) {
|
|
86
|
+
try {
|
|
87
|
+
const shouldContinue = await backoff.wait();
|
|
88
|
+
if (!shouldContinue) {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// For other errors, throw
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const elapsed = Date.now() - startTime;
|
|
102
|
+
// If we don't have a status, create a placeholder
|
|
103
|
+
if (!lastStatus) {
|
|
104
|
+
lastStatus = {
|
|
105
|
+
id: jobId,
|
|
106
|
+
status: timedOut ? 'partial' : 'failed',
|
|
107
|
+
errors: [{ message: timedOut ? 'Polling timed out' : 'Polling aborted' }],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
else if (timedOut && !this.isTerminalStatus(lastStatus.status)) {
|
|
111
|
+
// Mark as partial if timed out while still running
|
|
112
|
+
lastStatus = {
|
|
113
|
+
...lastStatus,
|
|
114
|
+
status: 'partial',
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
status: lastStatus,
|
|
119
|
+
timedOut,
|
|
120
|
+
elapsed,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Resume watching a batch job
|
|
125
|
+
*
|
|
126
|
+
* This is a convenience method that wraps watchJob for resuming
|
|
127
|
+
* a previously started job by its ID.
|
|
128
|
+
*/
|
|
129
|
+
async resumeJob(jobId, options) {
|
|
130
|
+
const generator = this.watchJob(jobId, options);
|
|
131
|
+
// Consume the generator
|
|
132
|
+
while (true) {
|
|
133
|
+
const result = await generator.next();
|
|
134
|
+
if (result.done) {
|
|
135
|
+
return result.value;
|
|
136
|
+
}
|
|
137
|
+
// Status updates are handled via the generator, we just continue
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get the current status of a batch job
|
|
142
|
+
*/
|
|
143
|
+
async getJobStatus(jobId, signal) {
|
|
144
|
+
const endpoint = `${this.baseEndpoint}/abilities/mainwp/get-batch-job-status-v1/run`;
|
|
145
|
+
const qs = `input[job_id]=${encodeURIComponent(jobId)}`;
|
|
146
|
+
const response = await this.httpClient.get(`${endpoint}?${qs}`, signal ? { signal } : undefined);
|
|
147
|
+
return this.normalizeJobStatus(response.data);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Check if a status is terminal (job finished)
|
|
151
|
+
*/
|
|
152
|
+
isTerminalStatus(status) {
|
|
153
|
+
return status === 'completed' || status === 'failed' || status === 'partial';
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Normalize API response to JobStatus, unwrapping success envelope if present
|
|
157
|
+
*/
|
|
158
|
+
normalizeJobStatus(data) {
|
|
159
|
+
if (typeof data !== 'object' || data === null) {
|
|
160
|
+
throw new APIError('INVALID_RESPONSE', 'Invalid job status response');
|
|
161
|
+
}
|
|
162
|
+
const response = data;
|
|
163
|
+
// Unwrap success envelope if present
|
|
164
|
+
let fields = response;
|
|
165
|
+
if ('success' in response && 'data' in response) {
|
|
166
|
+
const inner = response['data'];
|
|
167
|
+
if (typeof inner !== 'object' || inner === null || Array.isArray(inner)) {
|
|
168
|
+
throw new APIError('INVALID_RESPONSE', 'Invalid job status data in success envelope');
|
|
169
|
+
}
|
|
170
|
+
fields = inner;
|
|
171
|
+
}
|
|
172
|
+
const id = String(fields['job_id'] ?? fields['id'] ?? '');
|
|
173
|
+
if (!id) {
|
|
174
|
+
throw new APIError('INVALID_RESPONSE', 'Job status response missing job ID');
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
id,
|
|
178
|
+
status: this.parseJobStatus(fields['status']),
|
|
179
|
+
progress: typeof fields['progress'] === 'number' ? fields['progress'] : undefined,
|
|
180
|
+
total: typeof fields['total'] === 'number' ? fields['total'] : undefined,
|
|
181
|
+
processed: typeof fields['processed'] === 'number' ? fields['processed'] : undefined,
|
|
182
|
+
results: Array.isArray(fields['results']) ? fields['results'] : undefined,
|
|
183
|
+
errors: this.parseJobErrors(fields['errors']),
|
|
184
|
+
created_at: typeof fields['created_at'] === 'string' ? fields['created_at'] : undefined,
|
|
185
|
+
completed_at: typeof fields['completed_at'] === 'string' ? fields['completed_at'] : undefined,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Parse job status string
|
|
190
|
+
*/
|
|
191
|
+
parseJobStatus(value) {
|
|
192
|
+
if (typeof value !== 'string') {
|
|
193
|
+
return 'pending';
|
|
194
|
+
}
|
|
195
|
+
const status = value.toLowerCase();
|
|
196
|
+
switch (status) {
|
|
197
|
+
case 'pending':
|
|
198
|
+
case 'running':
|
|
199
|
+
case 'completed':
|
|
200
|
+
case 'failed':
|
|
201
|
+
case 'partial':
|
|
202
|
+
return status;
|
|
203
|
+
case 'processing':
|
|
204
|
+
case 'in_progress':
|
|
205
|
+
return 'running';
|
|
206
|
+
case 'done':
|
|
207
|
+
case 'success':
|
|
208
|
+
return 'completed';
|
|
209
|
+
case 'error':
|
|
210
|
+
return 'failed';
|
|
211
|
+
default:
|
|
212
|
+
return 'pending';
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Parse job errors
|
|
217
|
+
*/
|
|
218
|
+
parseJobErrors(value) {
|
|
219
|
+
if (!Array.isArray(value)) {
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
return value.map((error) => {
|
|
223
|
+
if (typeof error === 'string') {
|
|
224
|
+
return { message: error, item: undefined, code: undefined };
|
|
225
|
+
}
|
|
226
|
+
if (typeof error === 'object' && error !== null) {
|
|
227
|
+
const e = error;
|
|
228
|
+
return {
|
|
229
|
+
item: e['item'],
|
|
230
|
+
message: String(e['message'] ?? e['error'] ?? 'Unknown error'),
|
|
231
|
+
code: typeof e['code'] === 'string' ? e['code'] : undefined,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
return { message: String(error), item: undefined, code: undefined };
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Create a batch manager from configuration
|
|
240
|
+
*/
|
|
241
|
+
export function createBatchManager(config) {
|
|
242
|
+
return new BatchManager(config);
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=batch-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-manager.js","sourceRoot":"","sources":["../../src/core/batch-manager.ts"],"names":[],"mappings":"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"}
|