katanakit-js 3.1.2 → 3.2.1
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 +559 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +2 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/notion/index.d.ts +3 -0
- package/dist/adapters/notion/index.d.ts.map +1 -0
- package/dist/adapters/notion/index.js +2 -0
- package/dist/adapters/notion/index.js.map +1 -0
- package/dist/adapters/notion/notion.service.d.ts +397 -0
- package/dist/adapters/notion/notion.service.d.ts.map +1 -0
- package/dist/adapters/notion/notion.service.js +604 -0
- package/dist/adapters/notion/notion.service.js.map +1 -0
- package/dist/adapters/wordpress/index.d.ts +3 -0
- package/dist/adapters/wordpress/index.d.ts.map +1 -0
- package/dist/adapters/wordpress/index.js +2 -0
- package/dist/adapters/wordpress/index.js.map +1 -0
- package/dist/adapters/wordpress/wordpress.service.d.ts +685 -0
- package/dist/adapters/wordpress/wordpress.service.d.ts.map +1 -0
- package/dist/adapters/wordpress/wordpress.service.js +1100 -0
- package/dist/adapters/wordpress/wordpress.service.js.map +1 -0
- package/dist/types/index.d.ts +767 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +14 -2
|
@@ -0,0 +1,1100 @@
|
|
|
1
|
+
/** Default WordPress REST API namespace. */
|
|
2
|
+
const WP_API_NAMESPACE = "wp/v2";
|
|
3
|
+
/** Module-level WordPress configuration. */
|
|
4
|
+
let config = null;
|
|
5
|
+
/**
|
|
6
|
+
* Retrieves the registered WordPress config or throws.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
function getConfig() {
|
|
10
|
+
if (!config) {
|
|
11
|
+
throw new Error("[WordPress] Not configured. Call useInitWordPress() first.");
|
|
12
|
+
}
|
|
13
|
+
return config;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Builds the base API URL from config.
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
function getApiBase() {
|
|
20
|
+
const { baseUrl, apiNamespace } = getConfig();
|
|
21
|
+
const ns = apiNamespace ?? WP_API_NAMESPACE;
|
|
22
|
+
const cleanBase = baseUrl.replace(/\/+$/, "");
|
|
23
|
+
return `${cleanBase}/wp-json/${ns}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Builds authentication headers from config.
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
function getAuthHeaders() {
|
|
30
|
+
const { auth } = getConfig();
|
|
31
|
+
if (!auth)
|
|
32
|
+
return {};
|
|
33
|
+
switch (auth.type) {
|
|
34
|
+
case "application-passwords":
|
|
35
|
+
case "basic": {
|
|
36
|
+
const credentials = btoa(`${auth.username}:${auth.password}`);
|
|
37
|
+
return { Authorization: `Basic ${credentials}` };
|
|
38
|
+
}
|
|
39
|
+
case "jwt":
|
|
40
|
+
return { Authorization: `Bearer ${auth.token}` };
|
|
41
|
+
case "nonce":
|
|
42
|
+
return { "X-WP-Nonce": auth.nonce };
|
|
43
|
+
default:
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Converts query params to URL search params.
|
|
49
|
+
* Handles _fields (string), _embed (boolean or string), and arrays.
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
function buildQueryParams(options) {
|
|
53
|
+
if (!options)
|
|
54
|
+
return "";
|
|
55
|
+
const params = new URLSearchParams();
|
|
56
|
+
for (const [key, value] of Object.entries(options)) {
|
|
57
|
+
if (value === undefined || value === null)
|
|
58
|
+
continue;
|
|
59
|
+
if (key === "_embed") {
|
|
60
|
+
// _embed can be: true (embed all), false (skip), or "author,wp:featuredmedia" (specific)
|
|
61
|
+
if (value === true) {
|
|
62
|
+
params.set("_embed", "");
|
|
63
|
+
}
|
|
64
|
+
else if (value === false) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
else if (typeof value === "string" && value) {
|
|
68
|
+
params.set("_embed", value);
|
|
69
|
+
}
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (key === "_fields") {
|
|
73
|
+
// _fields is always a string: "id,title,link"
|
|
74
|
+
if (typeof value === "string" && value) {
|
|
75
|
+
params.set("_fields", value);
|
|
76
|
+
}
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (Array.isArray(value)) {
|
|
80
|
+
params.set(key, value.join(","));
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
params.set(key, String(value));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const qs = params.toString();
|
|
87
|
+
return qs ? `?${qs}` : "";
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Internal helper to make requests to the WordPress REST API.
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
93
|
+
async function wpFetch(endpoint, options = {}) {
|
|
94
|
+
const url = `${getApiBase()}${endpoint}`;
|
|
95
|
+
try {
|
|
96
|
+
const response = await fetch(url, {
|
|
97
|
+
...options,
|
|
98
|
+
headers: {
|
|
99
|
+
"Content-Type": "application/json",
|
|
100
|
+
...getAuthHeaders(),
|
|
101
|
+
...options.headers,
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
const errorBody = await response.text().catch(() => null);
|
|
106
|
+
return {
|
|
107
|
+
data: null,
|
|
108
|
+
error: {
|
|
109
|
+
message: `WordPress API Error: ${response.statusText}`,
|
|
110
|
+
status: response.status,
|
|
111
|
+
details: errorBody,
|
|
112
|
+
},
|
|
113
|
+
url,
|
|
114
|
+
status: response.status,
|
|
115
|
+
ok: false,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (response.status === 204) {
|
|
119
|
+
return {
|
|
120
|
+
data: null,
|
|
121
|
+
error: null,
|
|
122
|
+
url,
|
|
123
|
+
status: 204,
|
|
124
|
+
ok: true,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const data = (await response.json());
|
|
128
|
+
return { data, error: null, url, status: response.status, ok: true };
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
132
|
+
return {
|
|
133
|
+
data: null,
|
|
134
|
+
error: { message: `Network Error: ${message}`, status: 0 },
|
|
135
|
+
url,
|
|
136
|
+
status: 0,
|
|
137
|
+
ok: false,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Internal helper for multipart file uploads.
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
145
|
+
async function wpUpload(endpoint, file, meta) {
|
|
146
|
+
const url = `${getApiBase()}${endpoint}`;
|
|
147
|
+
try {
|
|
148
|
+
const formData = new FormData();
|
|
149
|
+
// Add the file
|
|
150
|
+
if (typeof Buffer !== "undefined" && file instanceof Buffer) {
|
|
151
|
+
const blob = new Blob([new Uint8Array(file)]);
|
|
152
|
+
formData.append("file", blob, "upload");
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
formData.append("file", file, file.name ?? "upload");
|
|
156
|
+
}
|
|
157
|
+
// Add metadata
|
|
158
|
+
if (meta) {
|
|
159
|
+
for (const [key, value] of Object.entries(meta)) {
|
|
160
|
+
if (value !== undefined && value !== null) {
|
|
161
|
+
formData.append(key, String(value));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const response = await fetch(url, {
|
|
166
|
+
method: "POST",
|
|
167
|
+
headers: {
|
|
168
|
+
...getAuthHeaders(),
|
|
169
|
+
// Don't set Content-Type — browser sets multipart boundary
|
|
170
|
+
},
|
|
171
|
+
body: formData,
|
|
172
|
+
});
|
|
173
|
+
if (!response.ok) {
|
|
174
|
+
const errorBody = await response.text().catch(() => null);
|
|
175
|
+
return {
|
|
176
|
+
data: null,
|
|
177
|
+
error: {
|
|
178
|
+
message: `WordPress Upload Error: ${response.statusText}`,
|
|
179
|
+
status: response.status,
|
|
180
|
+
details: errorBody,
|
|
181
|
+
},
|
|
182
|
+
url,
|
|
183
|
+
status: response.status,
|
|
184
|
+
ok: false,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
const data = (await response.json());
|
|
188
|
+
return { data, error: null, url, status: response.status, ok: true };
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
192
|
+
return {
|
|
193
|
+
data: null,
|
|
194
|
+
error: { message: `Upload Error: ${message}`, status: 0 },
|
|
195
|
+
url,
|
|
196
|
+
status: 0,
|
|
197
|
+
ok: false,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/* -------------------------------------------------------------------------- */
|
|
202
|
+
/* Initialization */
|
|
203
|
+
/* -------------------------------------------------------------------------- */
|
|
204
|
+
/**
|
|
205
|
+
* Registers the WordPress REST API configuration. Call this once before
|
|
206
|
+
* any other WordPress function.
|
|
207
|
+
*
|
|
208
|
+
* Supports multiple auth methods: Application Passwords (recommended for
|
|
209
|
+
* plugins), JWT tokens, Basic Auth, and nonce-based auth for themes.
|
|
210
|
+
*
|
|
211
|
+
* @param cfg - Site URL, authentication method, and optional API namespace.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```ts
|
|
215
|
+
* import { useInitWordPress } from "katanakit-js/adapters/wordpress";
|
|
216
|
+
*
|
|
217
|
+
* // With Application Passwords (recommended)
|
|
218
|
+
* useInitWordPress({
|
|
219
|
+
* baseUrl: "https://mysite.com",
|
|
220
|
+
* auth: { type: "application-passwords", username: "admin", password: "xxxx xxxx xxxx" },
|
|
221
|
+
* });
|
|
222
|
+
*
|
|
223
|
+
* // With JWT
|
|
224
|
+
* useInitWordPress({
|
|
225
|
+
* baseUrl: "https://mysite.com",
|
|
226
|
+
* auth: { type: "jwt", token: "eyJhbGci..." },
|
|
227
|
+
* });
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
export function useInitWordPress(cfg) {
|
|
231
|
+
config = { ...cfg };
|
|
232
|
+
}
|
|
233
|
+
/* -------------------------------------------------------------------------- */
|
|
234
|
+
/* Posts */
|
|
235
|
+
/* -------------------------------------------------------------------------- */
|
|
236
|
+
/**
|
|
237
|
+
* Retrieves a list of WordPress posts with optional filtering and pagination.
|
|
238
|
+
*
|
|
239
|
+
* Use to display blog listings, search posts, or filter by category/tag/status.
|
|
240
|
+
* Returns a single page of results (default 10 per page).
|
|
241
|
+
*
|
|
242
|
+
* @param options - Query params: `per_page`, `page`, `search`, `categories`,
|
|
243
|
+
* `tags`, `status`, `orderby`, `order`, `_embed`, etc.
|
|
244
|
+
* @returns Array of posts.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* // Get latest 5 published posts
|
|
249
|
+
* const result = await useWpGetPosts({ per_page: 5, status: "publish" });
|
|
250
|
+
*
|
|
251
|
+
* // Search posts by keyword
|
|
252
|
+
* const result = await useWpGetPosts({ search: "tutorial" });
|
|
253
|
+
*
|
|
254
|
+
* // Get posts from category 3, sorted by title
|
|
255
|
+
* const result = await useWpGetPosts({ categories: 3, orderby: "title", order: "asc" });
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
export async function useWpGetPosts(options) {
|
|
259
|
+
return wpFetch(`/posts${buildQueryParams(options)}`);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Retrieves a single WordPress post by ID.
|
|
263
|
+
*
|
|
264
|
+
* @param id - The post ID.
|
|
265
|
+
* @param options - Optional query params (e.g. _embed for featured media).
|
|
266
|
+
* @returns The post object.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* const result = await useWpGetPost(42, { _embed: true });
|
|
271
|
+
* if (result.ok) console.log(result.data.title.rendered);
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
export async function useWpGetPost(id, options) {
|
|
275
|
+
return wpFetch(`/posts/${id}${buildQueryParams(options)}`);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Creates a new WordPress post.
|
|
279
|
+
*
|
|
280
|
+
* Use to publish blog entries, create drafts, or schedule future posts.
|
|
281
|
+
* The post will be assigned to the authenticated user by default.
|
|
282
|
+
*
|
|
283
|
+
* @param data - Post data: `title`, `content` (HTML), `status` (publish/draft/pending),
|
|
284
|
+
* `categories`, `tags`, `featured_media`, `excerpt`, `slug`, `date`, etc.
|
|
285
|
+
* @returns The created post.
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```ts
|
|
289
|
+
* // Publish immediately
|
|
290
|
+
* const result = await useWpCreatePost({
|
|
291
|
+
* title: "My New Post",
|
|
292
|
+
* content: "<p>Hello World!</p>",
|
|
293
|
+
* status: "publish",
|
|
294
|
+
* categories: [1, 3],
|
|
295
|
+
* });
|
|
296
|
+
*
|
|
297
|
+
* // Create as draft
|
|
298
|
+
* await useWpCreatePost({ title: "Draft Post", content: "...", status: "draft" });
|
|
299
|
+
* ```
|
|
300
|
+
*/
|
|
301
|
+
export async function useWpCreatePost(data) {
|
|
302
|
+
return wpFetch("/posts", {
|
|
303
|
+
method: "POST",
|
|
304
|
+
body: JSON.stringify(data),
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Updates an existing WordPress post.
|
|
309
|
+
*
|
|
310
|
+
* @param id - The post ID to update.
|
|
311
|
+
* @param data - Fields to update.
|
|
312
|
+
* @returns The updated post.
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```ts
|
|
316
|
+
* await useWpUpdatePost(42, { title: "Updated Title" });
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
export async function useWpUpdatePost(id, data) {
|
|
320
|
+
return wpFetch(`/posts/${id}`, {
|
|
321
|
+
method: "POST",
|
|
322
|
+
body: JSON.stringify(data),
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Deletes a WordPress post.
|
|
327
|
+
*
|
|
328
|
+
* @param id - The post ID to delete.
|
|
329
|
+
* @param force - If true, permanently deletes. If false, moves to trash.
|
|
330
|
+
* @returns The deleted post.
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```ts
|
|
334
|
+
* await useWpDeletePost(42); // Move to trash
|
|
335
|
+
* await useWpDeletePost(42, true); // Permanently delete
|
|
336
|
+
* ```
|
|
337
|
+
*/
|
|
338
|
+
export async function useWpDeletePost(id, force = false) {
|
|
339
|
+
return wpFetch(`/posts/${id}?force=${force}`, {
|
|
340
|
+
method: "DELETE",
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
/* -------------------------------------------------------------------------- */
|
|
344
|
+
/* Pages */
|
|
345
|
+
/* -------------------------------------------------------------------------- */
|
|
346
|
+
/**
|
|
347
|
+
* Retrieves a list of WordPress pages.
|
|
348
|
+
*
|
|
349
|
+
* @param options - Query params for filtering, sorting, and pagination.
|
|
350
|
+
* @returns Array of pages.
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```ts
|
|
354
|
+
* const result = await useWpGetPages({ per_page: 20 });
|
|
355
|
+
* ```
|
|
356
|
+
*/
|
|
357
|
+
export async function useWpGetPages(options) {
|
|
358
|
+
return wpFetch(`/pages${buildQueryParams(options)}`);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Retrieves a single WordPress page by ID.
|
|
362
|
+
*
|
|
363
|
+
* @param id - The page ID.
|
|
364
|
+
* @param options - Optional query params.
|
|
365
|
+
* @returns The page object.
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* ```ts
|
|
369
|
+
* const result = await useWpGetPage(10);
|
|
370
|
+
* if (result.ok) console.log(result.data.title.rendered);
|
|
371
|
+
* ```
|
|
372
|
+
*/
|
|
373
|
+
export async function useWpGetPage(id, options) {
|
|
374
|
+
return wpFetch(`/pages/${id}${buildQueryParams(options)}`);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Creates a new WordPress page.
|
|
378
|
+
*
|
|
379
|
+
* @param data - Page data (title, content, parent, etc.).
|
|
380
|
+
* @returns The created page.
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```ts
|
|
384
|
+
* await useWpCreatePage({
|
|
385
|
+
* title: "About Us",
|
|
386
|
+
* content: "<p>Welcome to our site!</p>",
|
|
387
|
+
* status: "publish",
|
|
388
|
+
* });
|
|
389
|
+
* ```
|
|
390
|
+
*/
|
|
391
|
+
export async function useWpCreatePage(data) {
|
|
392
|
+
return wpFetch("/pages", {
|
|
393
|
+
method: "POST",
|
|
394
|
+
body: JSON.stringify(data),
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Updates an existing WordPress page.
|
|
399
|
+
*
|
|
400
|
+
* @param id - The page ID to update.
|
|
401
|
+
* @param data - Fields to update.
|
|
402
|
+
* @returns The updated page.
|
|
403
|
+
*
|
|
404
|
+
* @example
|
|
405
|
+
* ```ts
|
|
406
|
+
* await useWpUpdatePage(10, { title: "Updated About" });
|
|
407
|
+
* ```
|
|
408
|
+
*/
|
|
409
|
+
export async function useWpUpdatePage(id, data) {
|
|
410
|
+
return wpFetch(`/pages/${id}`, {
|
|
411
|
+
method: "POST",
|
|
412
|
+
body: JSON.stringify(data),
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Deletes a WordPress page.
|
|
417
|
+
*
|
|
418
|
+
* @param id - The page ID to delete.
|
|
419
|
+
* @param force - If true, permanently deletes. If false, moves to trash.
|
|
420
|
+
* @returns The deleted page.
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```ts
|
|
424
|
+
* await useWpDeletePage(10); // Move to trash
|
|
425
|
+
* ```
|
|
426
|
+
*/
|
|
427
|
+
export async function useWpDeletePage(id, force = false) {
|
|
428
|
+
return wpFetch(`/pages/${id}?force=${force}`, {
|
|
429
|
+
method: "DELETE",
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
/* -------------------------------------------------------------------------- */
|
|
433
|
+
/* Media */
|
|
434
|
+
/* -------------------------------------------------------------------------- */
|
|
435
|
+
/**
|
|
436
|
+
* Retrieves a list of WordPress media items.
|
|
437
|
+
*
|
|
438
|
+
* @param options - Query params for filtering and pagination.
|
|
439
|
+
* @returns Array of media items.
|
|
440
|
+
*
|
|
441
|
+
* @example
|
|
442
|
+
* ```ts
|
|
443
|
+
* const result = await useWpGetMedia({ per_page: 20 });
|
|
444
|
+
* ```
|
|
445
|
+
*/
|
|
446
|
+
export async function useWpGetMedia(options) {
|
|
447
|
+
return wpFetch(`/media${buildQueryParams(options)}`);
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Retrieves a single WordPress media item by ID.
|
|
451
|
+
*
|
|
452
|
+
* @param id - The media item ID.
|
|
453
|
+
* @returns The media object.
|
|
454
|
+
*
|
|
455
|
+
* @example
|
|
456
|
+
* ```ts
|
|
457
|
+
* const result = await useWpGetMediaItem(42);
|
|
458
|
+
* if (result.ok) console.log(result.data.source_url);
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
export async function useWpGetMediaItem(id) {
|
|
462
|
+
return wpFetch(`/media/${id}`);
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Uploads a file to the WordPress media library.
|
|
466
|
+
*
|
|
467
|
+
* Use to upload images, documents, or any file type supported by WordPress.
|
|
468
|
+
* Returns the media item with its URL for use as featured media or in content.
|
|
469
|
+
*
|
|
470
|
+
* @param file - File (browser), Blob, or Buffer (Node.js) to upload.
|
|
471
|
+
* @param meta - Optional metadata: `title`, `alt_text`, `caption`, `description`,
|
|
472
|
+
* `post` (attach to existing post), `slug`.
|
|
473
|
+
* @returns The created media item with `source_url`.
|
|
474
|
+
*
|
|
475
|
+
* @example
|
|
476
|
+
* ```ts
|
|
477
|
+
* // From a file input (browser)
|
|
478
|
+
* const file = document.querySelector("input[type=file]").files[0];
|
|
479
|
+
* const result = await useWpUploadMedia(file, {
|
|
480
|
+
* title: "My Image",
|
|
481
|
+
* alt_text: "Description for accessibility",
|
|
482
|
+
* });
|
|
483
|
+
* if (result.ok) console.log(result.data.source_url); // URL to use in content
|
|
484
|
+
*
|
|
485
|
+
* // From a Buffer (Node.js)
|
|
486
|
+
* const buffer = fs.readFileSync("photo.jpg");
|
|
487
|
+
* await useWpUploadMedia(buffer, { title: "Photo" });
|
|
488
|
+
* ```
|
|
489
|
+
*/
|
|
490
|
+
export async function useWpUploadMedia(file, meta) {
|
|
491
|
+
return wpUpload("/media", file, meta);
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Updates metadata of a WordPress media item.
|
|
495
|
+
*
|
|
496
|
+
* @param id - The media item ID.
|
|
497
|
+
* @param data - Fields to update.
|
|
498
|
+
* @returns The updated media item.
|
|
499
|
+
*
|
|
500
|
+
* @example
|
|
501
|
+
* ```ts
|
|
502
|
+
* await useWpUpdateMedia(42, { alt_text: "New alt text" });
|
|
503
|
+
* ```
|
|
504
|
+
*/
|
|
505
|
+
export async function useWpUpdateMedia(id, data) {
|
|
506
|
+
return wpFetch(`/media/${id}`, {
|
|
507
|
+
method: "POST",
|
|
508
|
+
body: JSON.stringify(data),
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Deletes a WordPress media item.
|
|
513
|
+
*
|
|
514
|
+
* @param id - The media item ID.
|
|
515
|
+
* @param force - If true, permanently deletes.
|
|
516
|
+
* @returns The deleted media item.
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* ```ts
|
|
520
|
+
* await useWpDeleteMedia(42, true);
|
|
521
|
+
* ```
|
|
522
|
+
*/
|
|
523
|
+
export async function useWpDeleteMedia(id, force = false) {
|
|
524
|
+
return wpFetch(`/media/${id}?force=${force}`, {
|
|
525
|
+
method: "DELETE",
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
/* -------------------------------------------------------------------------- */
|
|
529
|
+
/* Categories */
|
|
530
|
+
/* -------------------------------------------------------------------------- */
|
|
531
|
+
/**
|
|
532
|
+
* Retrieves a list of WordPress categories.
|
|
533
|
+
*
|
|
534
|
+
* @param options - Query params for filtering and pagination.
|
|
535
|
+
* @returns Array of categories.
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```ts
|
|
539
|
+
* const result = await useWpGetCategories({ per_page: 50 });
|
|
540
|
+
* if (result.ok) result.data.forEach(c => console.log(c.name));
|
|
541
|
+
* ```
|
|
542
|
+
*/
|
|
543
|
+
export async function useWpGetCategories(options) {
|
|
544
|
+
return wpFetch(`/categories${buildQueryParams(options)}`);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Retrieves a single WordPress category by ID.
|
|
548
|
+
*
|
|
549
|
+
* @param id - The category ID.
|
|
550
|
+
* @returns The category object.
|
|
551
|
+
*
|
|
552
|
+
* @example
|
|
553
|
+
* ```ts
|
|
554
|
+
* const result = await useWpGetCategory(5);
|
|
555
|
+
* if (result.ok) console.log(result.data.name);
|
|
556
|
+
* ```
|
|
557
|
+
*/
|
|
558
|
+
export async function useWpGetCategory(id) {
|
|
559
|
+
return wpFetch(`/categories/${id}`);
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Creates a new WordPress category.
|
|
563
|
+
*
|
|
564
|
+
* @param data - Category data (name, slug, parent, etc.).
|
|
565
|
+
* @returns The created category.
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* ```ts
|
|
569
|
+
* await useWpCreateCategory({ name: "Technology", slug: "tech" });
|
|
570
|
+
* ```
|
|
571
|
+
*/
|
|
572
|
+
export async function useWpCreateCategory(data) {
|
|
573
|
+
return wpFetch("/categories", {
|
|
574
|
+
method: "POST",
|
|
575
|
+
body: JSON.stringify(data),
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Updates an existing WordPress category.
|
|
580
|
+
*
|
|
581
|
+
* @param id - The category ID to update.
|
|
582
|
+
* @param data - Fields to update.
|
|
583
|
+
* @returns The updated category.
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* ```ts
|
|
587
|
+
* await useWpUpdateCategory(5, { name: "Tech News" });
|
|
588
|
+
* ```
|
|
589
|
+
*/
|
|
590
|
+
export async function useWpUpdateCategory(id, data) {
|
|
591
|
+
return wpFetch(`/categories/${id}`, {
|
|
592
|
+
method: "POST",
|
|
593
|
+
body: JSON.stringify(data),
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Deletes a WordPress category.
|
|
598
|
+
*
|
|
599
|
+
* @param id - The category ID to delete.
|
|
600
|
+
* @param force - If true, permanently deletes.
|
|
601
|
+
* @returns The deleted category.
|
|
602
|
+
*
|
|
603
|
+
* @example
|
|
604
|
+
* ```ts
|
|
605
|
+
* await useWpDeleteCategory(5);
|
|
606
|
+
* ```
|
|
607
|
+
*/
|
|
608
|
+
export async function useWpDeleteCategory(id, force = false) {
|
|
609
|
+
return wpFetch(`/categories/${id}?force=${force}`, {
|
|
610
|
+
method: "DELETE",
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
/* -------------------------------------------------------------------------- */
|
|
614
|
+
/* Tags */
|
|
615
|
+
/* -------------------------------------------------------------------------- */
|
|
616
|
+
/**
|
|
617
|
+
* Retrieves a list of WordPress tags.
|
|
618
|
+
*
|
|
619
|
+
* @param options - Query params for filtering and pagination.
|
|
620
|
+
* @returns Array of tags.
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* ```ts
|
|
624
|
+
* const result = await useWpGetTags({ search: "javascript" });
|
|
625
|
+
* ```
|
|
626
|
+
*/
|
|
627
|
+
export async function useWpGetTags(options) {
|
|
628
|
+
return wpFetch(`/tags${buildQueryParams(options)}`);
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Retrieves a single WordPress tag by ID.
|
|
632
|
+
*
|
|
633
|
+
* @param id - The tag ID.
|
|
634
|
+
* @returns The tag object.
|
|
635
|
+
*
|
|
636
|
+
* @example
|
|
637
|
+
* ```ts
|
|
638
|
+
* const result = await useWpGetTag(12);
|
|
639
|
+
* ```
|
|
640
|
+
*/
|
|
641
|
+
export async function useWpGetTag(id) {
|
|
642
|
+
return wpFetch(`/tags/${id}`);
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Creates a new WordPress tag.
|
|
646
|
+
*
|
|
647
|
+
* @param data - Tag data (name, slug, etc.).
|
|
648
|
+
* @returns The created tag.
|
|
649
|
+
*
|
|
650
|
+
* @example
|
|
651
|
+
* ```ts
|
|
652
|
+
* await useWpCreateTag({ name: "TypeScript", slug: "typescript" });
|
|
653
|
+
* ```
|
|
654
|
+
*/
|
|
655
|
+
export async function useWpCreateTag(data) {
|
|
656
|
+
return wpFetch("/tags", {
|
|
657
|
+
method: "POST",
|
|
658
|
+
body: JSON.stringify(data),
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Updates an existing WordPress tag.
|
|
663
|
+
*
|
|
664
|
+
* @param id - The tag ID to update.
|
|
665
|
+
* @param data - Fields to update.
|
|
666
|
+
* @returns The updated tag.
|
|
667
|
+
*
|
|
668
|
+
* @example
|
|
669
|
+
* ```ts
|
|
670
|
+
* await useWpUpdateTag(12, { name: "TS" });
|
|
671
|
+
* ```
|
|
672
|
+
*/
|
|
673
|
+
export async function useWpUpdateTag(id, data) {
|
|
674
|
+
return wpFetch(`/tags/${id}`, {
|
|
675
|
+
method: "POST",
|
|
676
|
+
body: JSON.stringify(data),
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Deletes a WordPress tag.
|
|
681
|
+
*
|
|
682
|
+
* @param id - The tag ID to delete.
|
|
683
|
+
* @param force - If true, permanently deletes.
|
|
684
|
+
* @returns The deleted tag.
|
|
685
|
+
*
|
|
686
|
+
* @example
|
|
687
|
+
* ```ts
|
|
688
|
+
* await useWpDeleteTag(12);
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
export async function useWpDeleteTag(id, force = false) {
|
|
692
|
+
return wpFetch(`/tags/${id}?force=${force}`, {
|
|
693
|
+
method: "DELETE",
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
/* -------------------------------------------------------------------------- */
|
|
697
|
+
/* Comments */
|
|
698
|
+
/* -------------------------------------------------------------------------- */
|
|
699
|
+
/**
|
|
700
|
+
* Retrieves a list of WordPress comments.
|
|
701
|
+
*
|
|
702
|
+
* @param options - Query params for filtering and pagination.
|
|
703
|
+
* @returns Array of comments.
|
|
704
|
+
*
|
|
705
|
+
* @example
|
|
706
|
+
* ```ts
|
|
707
|
+
* // Get comments for a specific post
|
|
708
|
+
* const result = await useWpGetComments({ post: 42 });
|
|
709
|
+
* ```
|
|
710
|
+
*/
|
|
711
|
+
export async function useWpGetComments(options) {
|
|
712
|
+
return wpFetch(`/comments${buildQueryParams(options)}`);
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Retrieves a single WordPress comment by ID.
|
|
716
|
+
*
|
|
717
|
+
* @param id - The comment ID.
|
|
718
|
+
* @returns The comment object.
|
|
719
|
+
*
|
|
720
|
+
* @example
|
|
721
|
+
* ```ts
|
|
722
|
+
* const result = await useWpGetComment(7);
|
|
723
|
+
* ```
|
|
724
|
+
*/
|
|
725
|
+
export async function useWpGetComment(id) {
|
|
726
|
+
return wpFetch(`/comments/${id}`);
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Creates a new WordPress comment.
|
|
730
|
+
*
|
|
731
|
+
* @param data - Comment data (post ID, content, author, etc.).
|
|
732
|
+
* @returns The created comment.
|
|
733
|
+
*
|
|
734
|
+
* @example
|
|
735
|
+
* ```ts
|
|
736
|
+
* await useWpCreateComment({
|
|
737
|
+
* post: 42,
|
|
738
|
+
* content: "Great article!",
|
|
739
|
+
* author_name: "John",
|
|
740
|
+
* author_email: "john@example.com",
|
|
741
|
+
* });
|
|
742
|
+
* ```
|
|
743
|
+
*/
|
|
744
|
+
export async function useWpCreateComment(data) {
|
|
745
|
+
return wpFetch("/comments", {
|
|
746
|
+
method: "POST",
|
|
747
|
+
body: JSON.stringify(data),
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Updates an existing WordPress comment.
|
|
752
|
+
*
|
|
753
|
+
* @param id - The comment ID to update.
|
|
754
|
+
* @param data - Fields to update.
|
|
755
|
+
* @returns The updated comment.
|
|
756
|
+
*
|
|
757
|
+
* @example
|
|
758
|
+
* ```ts
|
|
759
|
+
* await useWpUpdateComment(7, { content: "Updated comment" });
|
|
760
|
+
* ```
|
|
761
|
+
*/
|
|
762
|
+
export async function useWpUpdateComment(id, data) {
|
|
763
|
+
return wpFetch(`/comments/${id}`, {
|
|
764
|
+
method: "POST",
|
|
765
|
+
body: JSON.stringify(data),
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Deletes a WordPress comment.
|
|
770
|
+
*
|
|
771
|
+
* @param id - The comment ID to delete.
|
|
772
|
+
* @param force - If true, permanently deletes.
|
|
773
|
+
* @returns The deleted comment.
|
|
774
|
+
*
|
|
775
|
+
* @example
|
|
776
|
+
* ```ts
|
|
777
|
+
* await useWpDeleteComment(7);
|
|
778
|
+
* ```
|
|
779
|
+
*/
|
|
780
|
+
export async function useWpDeleteComment(id, force = false) {
|
|
781
|
+
return wpFetch(`/comments/${id}?force=${force}`, {
|
|
782
|
+
method: "DELETE",
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
/* -------------------------------------------------------------------------- */
|
|
786
|
+
/* Users */
|
|
787
|
+
/* -------------------------------------------------------------------------- */
|
|
788
|
+
/**
|
|
789
|
+
* Retrieves a list of WordPress users.
|
|
790
|
+
*
|
|
791
|
+
* @param options - Query params for filtering and pagination.
|
|
792
|
+
* @returns Array of users.
|
|
793
|
+
*
|
|
794
|
+
* @example
|
|
795
|
+
* ```ts
|
|
796
|
+
* const result = await useWpGetUsers({ roles: "editor" });
|
|
797
|
+
* ```
|
|
798
|
+
*/
|
|
799
|
+
export async function useWpGetUsers(options) {
|
|
800
|
+
return wpFetch(`/users${buildQueryParams(options)}`);
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* Retrieves a single WordPress user by ID.
|
|
804
|
+
*
|
|
805
|
+
* @param id - The user ID.
|
|
806
|
+
* @returns The user object.
|
|
807
|
+
*
|
|
808
|
+
* @example
|
|
809
|
+
* ```ts
|
|
810
|
+
* const result = await useWpGetUser(1);
|
|
811
|
+
* if (result.ok) console.log(result.data.name);
|
|
812
|
+
* ```
|
|
813
|
+
*/
|
|
814
|
+
export async function useWpGetUser(id) {
|
|
815
|
+
return wpFetch(`/users/${id}`);
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Retrieves the currently authenticated WordPress user.
|
|
819
|
+
*
|
|
820
|
+
* @returns The current user object.
|
|
821
|
+
*
|
|
822
|
+
* @example
|
|
823
|
+
* ```ts
|
|
824
|
+
* const result = await useWpGetCurrentUser();
|
|
825
|
+
* if (result.ok) console.log(result.data.email);
|
|
826
|
+
* ```
|
|
827
|
+
*/
|
|
828
|
+
export async function useWpGetCurrentUser() {
|
|
829
|
+
return wpFetch("/users/me");
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Creates a new WordPress user.
|
|
833
|
+
*
|
|
834
|
+
* @param data - User data (username, email, password, etc.).
|
|
835
|
+
* @returns The created user.
|
|
836
|
+
*
|
|
837
|
+
* @example
|
|
838
|
+
* ```ts
|
|
839
|
+
* await useWpCreateUser({
|
|
840
|
+
* username: "johndoe",
|
|
841
|
+
* email: "john@example.com",
|
|
842
|
+
* password: "secure-password",
|
|
843
|
+
* roles: ["editor"],
|
|
844
|
+
* });
|
|
845
|
+
* ```
|
|
846
|
+
*/
|
|
847
|
+
export async function useWpCreateUser(data) {
|
|
848
|
+
return wpFetch("/users", {
|
|
849
|
+
method: "POST",
|
|
850
|
+
body: JSON.stringify(data),
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Updates an existing WordPress user.
|
|
855
|
+
*
|
|
856
|
+
* @param id - The user ID to update.
|
|
857
|
+
* @param data - Fields to update.
|
|
858
|
+
* @returns The updated user.
|
|
859
|
+
*
|
|
860
|
+
* @example
|
|
861
|
+
* ```ts
|
|
862
|
+
* await useWpUpdateUser(2, { name: "John Smith" });
|
|
863
|
+
* ```
|
|
864
|
+
*/
|
|
865
|
+
export async function useWpUpdateUser(id, data) {
|
|
866
|
+
return wpFetch(`/users/${id}`, {
|
|
867
|
+
method: "POST",
|
|
868
|
+
body: JSON.stringify(data),
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* Deletes a WordPress user.
|
|
873
|
+
*
|
|
874
|
+
* @param id - The user ID to delete.
|
|
875
|
+
* @param reassign - User ID to reassign content to (required for non-admin).
|
|
876
|
+
* @returns The deleted user.
|
|
877
|
+
*
|
|
878
|
+
* @example
|
|
879
|
+
* ```ts
|
|
880
|
+
* await useWpDeleteUser(2, 1); // Reassign content to user 1
|
|
881
|
+
* ```
|
|
882
|
+
*/
|
|
883
|
+
export async function useWpDeleteUser(id, reassign) {
|
|
884
|
+
const qs = reassign ? `?reassign=${reassign}` : "";
|
|
885
|
+
return wpFetch(`/users/${id}${qs}`, {
|
|
886
|
+
method: "DELETE",
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
/* -------------------------------------------------------------------------- */
|
|
890
|
+
/* Custom Post Types */
|
|
891
|
+
/* -------------------------------------------------------------------------- */
|
|
892
|
+
/**
|
|
893
|
+
* Retrieves a list of custom post type entries.
|
|
894
|
+
*
|
|
895
|
+
* @param postType - The custom post type slug (e.g. "product", "portfolio").
|
|
896
|
+
* @param options - Query params for filtering and pagination.
|
|
897
|
+
* @returns Array of custom post entries.
|
|
898
|
+
*
|
|
899
|
+
* @example
|
|
900
|
+
* ```ts
|
|
901
|
+
* const result = await useWpGetCustomPosts("product", { per_page: 10 });
|
|
902
|
+
* ```
|
|
903
|
+
*/
|
|
904
|
+
export async function useWpGetCustomPosts(postType, options) {
|
|
905
|
+
return wpFetch(`/${postType}${buildQueryParams(options)}`);
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Retrieves a single custom post type entry by ID.
|
|
909
|
+
*
|
|
910
|
+
* @param postType - The custom post type slug.
|
|
911
|
+
* @param id - The entry ID.
|
|
912
|
+
* @param options - Optional query params.
|
|
913
|
+
* @returns The custom post entry.
|
|
914
|
+
*
|
|
915
|
+
* @example
|
|
916
|
+
* ```ts
|
|
917
|
+
* const result = await useWpGetCustomPost("product", 15);
|
|
918
|
+
* ```
|
|
919
|
+
*/
|
|
920
|
+
export async function useWpGetCustomPost(postType, id, options) {
|
|
921
|
+
return wpFetch(`/${postType}/${id}${buildQueryParams(options)}`);
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Creates a new custom post type entry.
|
|
925
|
+
*
|
|
926
|
+
* @param postType - The custom post type slug.
|
|
927
|
+
* @param data - Entry data.
|
|
928
|
+
* @returns The created entry.
|
|
929
|
+
*
|
|
930
|
+
* @example
|
|
931
|
+
* ```ts
|
|
932
|
+
* await useWpCreateCustomPost("product", {
|
|
933
|
+
* title: "Widget",
|
|
934
|
+
* content: "<p>A great widget</p>",
|
|
935
|
+
* status: "publish",
|
|
936
|
+
* });
|
|
937
|
+
* ```
|
|
938
|
+
*/
|
|
939
|
+
export async function useWpCreateCustomPost(postType, data) {
|
|
940
|
+
return wpFetch(`/${postType}`, {
|
|
941
|
+
method: "POST",
|
|
942
|
+
body: JSON.stringify(data),
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Updates a custom post type entry.
|
|
947
|
+
*
|
|
948
|
+
* @param postType - The custom post type slug.
|
|
949
|
+
* @param id - The entry ID.
|
|
950
|
+
* @param data - Fields to update.
|
|
951
|
+
* @returns The updated entry.
|
|
952
|
+
*
|
|
953
|
+
* @example
|
|
954
|
+
* ```ts
|
|
955
|
+
* await useWpUpdateCustomPost("product", 15, { title: "Updated Widget" });
|
|
956
|
+
* ```
|
|
957
|
+
*/
|
|
958
|
+
export async function useWpUpdateCustomPost(postType, id, data) {
|
|
959
|
+
return wpFetch(`/${postType}/${id}`, {
|
|
960
|
+
method: "POST",
|
|
961
|
+
body: JSON.stringify(data),
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Deletes a custom post type entry.
|
|
966
|
+
*
|
|
967
|
+
* @param postType - The custom post type slug.
|
|
968
|
+
* @param id - The entry ID.
|
|
969
|
+
* @param force - If true, permanently deletes.
|
|
970
|
+
* @returns The deleted entry.
|
|
971
|
+
*
|
|
972
|
+
* @example
|
|
973
|
+
* ```ts
|
|
974
|
+
* await useWpDeleteCustomPost("product", 15, true);
|
|
975
|
+
* ```
|
|
976
|
+
*/
|
|
977
|
+
export async function useWpDeleteCustomPost(postType, id, force = false) {
|
|
978
|
+
return wpFetch(`/${postType}/${id}?force=${force}`, {
|
|
979
|
+
method: "DELETE",
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
/* -------------------------------------------------------------------------- */
|
|
983
|
+
/* Batch Operations */
|
|
984
|
+
/* -------------------------------------------------------------------------- */
|
|
985
|
+
/**
|
|
986
|
+
* Executes multiple WordPress REST API requests in a single batch.
|
|
987
|
+
*
|
|
988
|
+
* @param operations - Array of batch operations to execute.
|
|
989
|
+
* @returns Combined results from all operations.
|
|
990
|
+
*
|
|
991
|
+
* @example
|
|
992
|
+
* ```ts
|
|
993
|
+
* const result = await useWpBatch([
|
|
994
|
+
* { method: "GET", path: "/wp/v2/posts/1" },
|
|
995
|
+
* { method: "POST", path: "/wp/v2/posts", body: { title: "New Post" } },
|
|
996
|
+
* ]);
|
|
997
|
+
* if (result.ok) console.log(result.data.responses);
|
|
998
|
+
* ```
|
|
999
|
+
*/
|
|
1000
|
+
export async function useWpBatch(operations) {
|
|
1001
|
+
return wpFetch("/batch/v1", {
|
|
1002
|
+
method: "POST",
|
|
1003
|
+
body: JSON.stringify({ requests: operations }),
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
/* -------------------------------------------------------------------------- */
|
|
1007
|
+
/* Pagination Helpers */
|
|
1008
|
+
/* -------------------------------------------------------------------------- */
|
|
1009
|
+
/**
|
|
1010
|
+
* Fetches ALL posts matching the criteria, automatically handling pagination.
|
|
1011
|
+
*
|
|
1012
|
+
* Use when you need every post (e.g. for sitemap generation, RSS feeds,
|
|
1013
|
+
* or data exports) without managing page numbers. Loops until all pages
|
|
1014
|
+
* are fetched.
|
|
1015
|
+
*
|
|
1016
|
+
* @param options - Query params for filtering (`status`, `categories`, `tags`,
|
|
1017
|
+
* `author`, `search`, `orderby`, `order`). Do NOT pass `page` or `per_page`.
|
|
1018
|
+
* @returns All posts as a flat array.
|
|
1019
|
+
*
|
|
1020
|
+
* @example
|
|
1021
|
+
* ```ts
|
|
1022
|
+
* // Get ALL published posts
|
|
1023
|
+
* const result = await useWpListAllPosts({ status: "publish" });
|
|
1024
|
+
* if (result.ok) console.log(`Total: ${result.data.length}`);
|
|
1025
|
+
*
|
|
1026
|
+
* // Get ALL posts from category 5
|
|
1027
|
+
* const cat5 = await useWpListAllPosts({ categories: 5 });
|
|
1028
|
+
* ```
|
|
1029
|
+
*/
|
|
1030
|
+
export async function useWpListAllPosts(options) {
|
|
1031
|
+
const allPosts = [];
|
|
1032
|
+
let page = 1;
|
|
1033
|
+
while (true) {
|
|
1034
|
+
const result = await useWpGetPosts({ ...options, page, per_page: 100 });
|
|
1035
|
+
if (!result.ok)
|
|
1036
|
+
return result;
|
|
1037
|
+
allPosts.push(...result.data);
|
|
1038
|
+
if (result.data.length < 100)
|
|
1039
|
+
break;
|
|
1040
|
+
page++;
|
|
1041
|
+
}
|
|
1042
|
+
return {
|
|
1043
|
+
data: allPosts,
|
|
1044
|
+
error: null,
|
|
1045
|
+
url: "",
|
|
1046
|
+
status: 200,
|
|
1047
|
+
ok: true,
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Searches ALL posts by keyword, automatically handling pagination.
|
|
1052
|
+
*
|
|
1053
|
+
* Use to find posts by title or content when you need every match,
|
|
1054
|
+
* not just the first page. Combines `search` param with auto-pagination.
|
|
1055
|
+
*
|
|
1056
|
+
* @param query - Search term (searches title and content).
|
|
1057
|
+
* @param options - Additional filters (`status`, `categories`, etc.).
|
|
1058
|
+
* @returns All posts matching the search.
|
|
1059
|
+
*
|
|
1060
|
+
* @example
|
|
1061
|
+
* ```ts
|
|
1062
|
+
* const result = await useWpSearchAllPosts("tutorial");
|
|
1063
|
+
* if (result.ok) result.data.forEach(p => console.log(p.title.rendered));
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
export async function useWpSearchAllPosts(query, options) {
|
|
1067
|
+
return useWpListAllPosts({ ...options, search: query });
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Finds a single post by its URL slug.
|
|
1071
|
+
*
|
|
1072
|
+
* Use for slug-based routing (e.g. `/blog/:slug` pages) where you need
|
|
1073
|
+
* to fetch a post by its human-readable URL identifier. Returns `null`
|
|
1074
|
+
* if no post matches the slug.
|
|
1075
|
+
*
|
|
1076
|
+
* @param slug - The post slug (e.g. "hello-world").
|
|
1077
|
+
* @returns The post or `null` if not found.
|
|
1078
|
+
*
|
|
1079
|
+
* @example
|
|
1080
|
+
* ```ts
|
|
1081
|
+
* // In an Astro/[slug].astro or similar dynamic route
|
|
1082
|
+
* const result = await useWpFindPostBySlug("hello-world");
|
|
1083
|
+
* if (result.ok && result.data) {
|
|
1084
|
+
* console.log(result.data.title.rendered);
|
|
1085
|
+
* }
|
|
1086
|
+
* ```
|
|
1087
|
+
*/
|
|
1088
|
+
export async function useWpFindPostBySlug(slug) {
|
|
1089
|
+
const result = await useWpGetPosts({ slug, per_page: 1 });
|
|
1090
|
+
if (!result.ok)
|
|
1091
|
+
return result;
|
|
1092
|
+
return {
|
|
1093
|
+
data: result.data[0] ?? null,
|
|
1094
|
+
error: null,
|
|
1095
|
+
url: result.url,
|
|
1096
|
+
status: result.status,
|
|
1097
|
+
ok: true,
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
//# sourceMappingURL=wordpress.service.js.map
|