@readpress/wp-blog 1.0.8 → 1.0.10
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 +11 -9
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +13 -1
- package/dist/index.mjs +13 -1
- package/dist/react.d.mts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/types-B9QucQ0W.d.mts +249 -0
- package/dist/types-B9QucQ0W.d.ts +249 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -4,8 +4,9 @@ A minimal, read-only headless WordPress blog adapter for modern web apps. Useful
|
|
|
4
4
|
|
|
5
5
|
- Fetch posts, authors, categories, and tags; includes post search
|
|
6
6
|
- Supports draft/private reads for preview flows with auth
|
|
7
|
-
- Next.js App Router docs and examples, with a framework-agnostic core.
|
|
8
7
|
- Read-only API (no write/update operations)
|
|
8
|
+
- Next.js App Router docs and examples, with a framework-agnostic core
|
|
9
|
+
- Docs ready for AI agent workflows (Codex, Cursor, Claude)
|
|
9
10
|
|
|
10
11
|
## Requirements
|
|
11
12
|
|
|
@@ -36,9 +37,10 @@ WP_REST_ENDPOINT=/wp-json/wp/v2/posts
|
|
|
36
37
|
|
|
37
38
|
- Configure `rewriteLinks` so internal links in WordPress content stay inside your app routes (for example `/blog/...`) instead of sending users to raw WordPress URLs.
|
|
38
39
|
- Configure `classNameMap` to replace class names in post HTML fetched from WordPress into your app (e.g., replace Gutenberg block class names with Tailwind classes in Next.js).
|
|
40
|
+
- Use `transformPostContentHtml` when you need custom post HTML transforms (e.g., sanitization).
|
|
39
41
|
|
|
40
42
|
## Quick start
|
|
41
|
-
See docs/quickstart.mdx
|
|
43
|
+
See [docs/quickstart.mdx](./docs/quickstart.mdx)
|
|
42
44
|
|
|
43
45
|
## AI-ready docs
|
|
44
46
|
|
|
@@ -49,13 +51,13 @@ Recommended:
|
|
|
49
51
|
- Or point your agent to the `docs/` folder in this repo on GitHub.
|
|
50
52
|
|
|
51
53
|
## Examples
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
54
|
+
- [examples/nextjs-blog](./examples/nextjs-blog/README.md)
|
|
55
|
+
- [examples/gutenberg-blocks-tailwind](./examples/gutenberg-blocks-tailwind/README.md)
|
|
56
|
+
- [examples/nextjs-post-components](./examples/nextjs-post-components/README.md)
|
|
55
57
|
|
|
56
58
|
## Advanced guides
|
|
57
59
|
|
|
58
|
-
- Drafts and preview:
|
|
59
|
-
- SEO in Next.js:
|
|
60
|
-
- Link rewriting:
|
|
61
|
-
- Class mapping (custom class names):
|
|
60
|
+
- Drafts and preview: [docs/guides/drafts-and-preview.mdx](./docs/guides/drafts-and-preview.mdx)
|
|
61
|
+
- SEO in Next.js: [docs/recipes/seo-nextjs.mdx](./docs/recipes/seo-nextjs.mdx)
|
|
62
|
+
- Link rewriting: [docs/content/link-rewriting.mdx](./docs/content/link-rewriting.mdx)
|
|
63
|
+
- Class mapping (custom class names): [docs/content/class-mapping.mdx](./docs/content/class-mapping.mdx)
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as PlaceholderParseOptions, W as WpContentPart, a as WpClientOptions, b as WpBlogClient, c as WpAuthor, G as GetAuthorsParams, d as GetTermsParams, B as BlogTerm, e as BlogPostField, f as GetPostParams, S as SelectFields, g as BlogPost, h as BlogPostSummaryField, i as GetPostsParams, j as PostListResult, k as BlogPostSummary, Q as QueryGraphqlParams, l as QueryGraphqlResult, m as QueryRawParams, n as SearchPostsParams } from './types-
|
|
2
|
-
export { o as BlogAuthor, p as BlogTermOrder, q as BlogTextMode, C as ClassNameMap, r as ClassNameMapMode, s as ClassNameMapRule, t as ClassNameMapValue, H as HtmlContentPart, L as LinkRewriteContext, u as LinkRewriteRule, v as PaginationMeta, w as PlaceholderContentPart, x as PlaceholderProps, y as QueryRawRestInput, z as WpAuthConfig, A as WpAuthResolvedConfig, D as WpAuthType, E as WpEmbedded, F as WpFeaturedMedia, I as WpPost, J as WpRenderedField, K as WpTerm } from './types-
|
|
1
|
+
import { P as PlaceholderParseOptions, W as WpContentPart, a as WpClientOptions, b as WpBlogClient, c as WpAuthor, G as GetAuthorsParams, d as GetTermsParams, B as BlogTerm, e as BlogPostField, f as GetPostParams, S as SelectFields, g as BlogPost, h as BlogPostSummaryField, i as GetPostsParams, j as PostListResult, k as BlogPostSummary, Q as QueryGraphqlParams, l as QueryGraphqlResult, m as QueryRawParams, n as SearchPostsParams } from './types-B9QucQ0W.mjs';
|
|
2
|
+
export { o as BlogAuthor, p as BlogTermOrder, q as BlogTextMode, C as ClassNameMap, r as ClassNameMapMode, s as ClassNameMapRule, t as ClassNameMapValue, H as HtmlContentPart, L as LinkRewriteContext, u as LinkRewriteRule, v as PaginationMeta, w as PlaceholderContentPart, x as PlaceholderProps, y as QueryRawRestInput, z as WpAuthConfig, A as WpAuthResolvedConfig, D as WpAuthType, E as WpEmbedded, F as WpFeaturedMedia, I as WpPost, J as WpRenderedField, K as WpTerm } from './types-B9QucQ0W.mjs';
|
|
3
3
|
|
|
4
4
|
type WpClientErrorCode = "INVALID_CONFIG" | "INVALID_INPUT" | "REQUEST_FAILED" | "INVALID_RESPONSE";
|
|
5
5
|
interface WpApiErrorDetails {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as PlaceholderParseOptions, W as WpContentPart, a as WpClientOptions, b as WpBlogClient, c as WpAuthor, G as GetAuthorsParams, d as GetTermsParams, B as BlogTerm, e as BlogPostField, f as GetPostParams, S as SelectFields, g as BlogPost, h as BlogPostSummaryField, i as GetPostsParams, j as PostListResult, k as BlogPostSummary, Q as QueryGraphqlParams, l as QueryGraphqlResult, m as QueryRawParams, n as SearchPostsParams } from './types-
|
|
2
|
-
export { o as BlogAuthor, p as BlogTermOrder, q as BlogTextMode, C as ClassNameMap, r as ClassNameMapMode, s as ClassNameMapRule, t as ClassNameMapValue, H as HtmlContentPart, L as LinkRewriteContext, u as LinkRewriteRule, v as PaginationMeta, w as PlaceholderContentPart, x as PlaceholderProps, y as QueryRawRestInput, z as WpAuthConfig, A as WpAuthResolvedConfig, D as WpAuthType, E as WpEmbedded, F as WpFeaturedMedia, I as WpPost, J as WpRenderedField, K as WpTerm } from './types-
|
|
1
|
+
import { P as PlaceholderParseOptions, W as WpContentPart, a as WpClientOptions, b as WpBlogClient, c as WpAuthor, G as GetAuthorsParams, d as GetTermsParams, B as BlogTerm, e as BlogPostField, f as GetPostParams, S as SelectFields, g as BlogPost, h as BlogPostSummaryField, i as GetPostsParams, j as PostListResult, k as BlogPostSummary, Q as QueryGraphqlParams, l as QueryGraphqlResult, m as QueryRawParams, n as SearchPostsParams } from './types-B9QucQ0W.js';
|
|
2
|
+
export { o as BlogAuthor, p as BlogTermOrder, q as BlogTextMode, C as ClassNameMap, r as ClassNameMapMode, s as ClassNameMapRule, t as ClassNameMapValue, H as HtmlContentPart, L as LinkRewriteContext, u as LinkRewriteRule, v as PaginationMeta, w as PlaceholderContentPart, x as PlaceholderProps, y as QueryRawRestInput, z as WpAuthConfig, A as WpAuthResolvedConfig, D as WpAuthType, E as WpEmbedded, F as WpFeaturedMedia, I as WpPost, J as WpRenderedField, K as WpTerm } from './types-B9QucQ0W.js';
|
|
3
3
|
|
|
4
4
|
type WpClientErrorCode = "INVALID_CONFIG" | "INVALID_INPUT" | "REQUEST_FAILED" | "INVALID_RESPONSE";
|
|
5
5
|
interface WpApiErrorDetails {
|
package/dist/index.js
CHANGED
|
@@ -323,6 +323,16 @@ function resolveClassNameMap(options) {
|
|
|
323
323
|
}
|
|
324
324
|
return map;
|
|
325
325
|
}
|
|
326
|
+
function resolveTransformPostContentHtml(options) {
|
|
327
|
+
const transform = options.transformPostContentHtml;
|
|
328
|
+
if (transform === void 0) {
|
|
329
|
+
return void 0;
|
|
330
|
+
}
|
|
331
|
+
if (typeof transform !== "function") {
|
|
332
|
+
throw new WpClientError("INVALID_CONFIG", "transformPostContentHtml must be a function.");
|
|
333
|
+
}
|
|
334
|
+
return transform;
|
|
335
|
+
}
|
|
326
336
|
function resolveClientOptions(options = {}) {
|
|
327
337
|
var _a, _b, _c, _d, _e;
|
|
328
338
|
const wpUrl = (_a = options.wpUrl) != null ? _a : readEnv("WP_URL");
|
|
@@ -346,6 +356,7 @@ function resolveClientOptions(options = {}) {
|
|
|
346
356
|
auth: resolveAuth(options),
|
|
347
357
|
rewriteLinks: resolveRewriteLinks(options),
|
|
348
358
|
classNameMap: resolveClassNameMap(options),
|
|
359
|
+
transformPostContentHtml: resolveTransformPostContentHtml(options),
|
|
349
360
|
fetchImpl,
|
|
350
361
|
requestInit: options.requestInit
|
|
351
362
|
};
|
|
@@ -1062,7 +1073,8 @@ function normalizePost(post, textMode = "plain", options) {
|
|
|
1062
1073
|
const summary = normalizePostSummary(post, textMode);
|
|
1063
1074
|
const rawContentHtml = (_b = (_a = post.content) == null ? void 0 : _a.rendered) != null ? _b : "";
|
|
1064
1075
|
const rewrittenHtml = options ? rewriteContentLinks(rawContentHtml, options) : rawContentHtml;
|
|
1065
|
-
const
|
|
1076
|
+
const classTransformedContentHtml = (options == null ? void 0 : options.classNameMap) && Object.keys(options.classNameMap).length > 0 ? transformContentClasses(rewrittenHtml, options.classNameMap) : rewrittenHtml;
|
|
1077
|
+
const contentHtml = (options == null ? void 0 : options.transformPostContentHtml) ? options.transformPostContentHtml(classTransformedContentHtml) : classTransformedContentHtml;
|
|
1066
1078
|
return __spreadProps(__spreadValues({}, summary), {
|
|
1067
1079
|
contentHtml
|
|
1068
1080
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -194,6 +194,16 @@ function resolveClassNameMap(options) {
|
|
|
194
194
|
}
|
|
195
195
|
return map;
|
|
196
196
|
}
|
|
197
|
+
function resolveTransformPostContentHtml(options) {
|
|
198
|
+
const transform = options.transformPostContentHtml;
|
|
199
|
+
if (transform === void 0) {
|
|
200
|
+
return void 0;
|
|
201
|
+
}
|
|
202
|
+
if (typeof transform !== "function") {
|
|
203
|
+
throw new WpClientError("INVALID_CONFIG", "transformPostContentHtml must be a function.");
|
|
204
|
+
}
|
|
205
|
+
return transform;
|
|
206
|
+
}
|
|
197
207
|
function resolveClientOptions(options = {}) {
|
|
198
208
|
var _a, _b, _c, _d, _e;
|
|
199
209
|
const wpUrl = (_a = options.wpUrl) != null ? _a : readEnv("WP_URL");
|
|
@@ -217,6 +227,7 @@ function resolveClientOptions(options = {}) {
|
|
|
217
227
|
auth: resolveAuth(options),
|
|
218
228
|
rewriteLinks: resolveRewriteLinks(options),
|
|
219
229
|
classNameMap: resolveClassNameMap(options),
|
|
230
|
+
transformPostContentHtml: resolveTransformPostContentHtml(options),
|
|
220
231
|
fetchImpl,
|
|
221
232
|
requestInit: options.requestInit
|
|
222
233
|
};
|
|
@@ -933,7 +944,8 @@ function normalizePost(post, textMode = "plain", options) {
|
|
|
933
944
|
const summary = normalizePostSummary(post, textMode);
|
|
934
945
|
const rawContentHtml = (_b = (_a = post.content) == null ? void 0 : _a.rendered) != null ? _b : "";
|
|
935
946
|
const rewrittenHtml = options ? rewriteContentLinks(rawContentHtml, options) : rawContentHtml;
|
|
936
|
-
const
|
|
947
|
+
const classTransformedContentHtml = (options == null ? void 0 : options.classNameMap) && Object.keys(options.classNameMap).length > 0 ? transformContentClasses(rewrittenHtml, options.classNameMap) : rewrittenHtml;
|
|
948
|
+
const contentHtml = (options == null ? void 0 : options.transformPostContentHtml) ? options.transformPostContentHtml(classTransformedContentHtml) : classTransformedContentHtml;
|
|
937
949
|
return __spreadProps(__spreadValues({}, summary), {
|
|
938
950
|
contentHtml
|
|
939
951
|
});
|
package/dist/react.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
|
-
import { W as WpContentPart } from './types-
|
|
3
|
+
import { W as WpContentPart } from './types-B9QucQ0W.mjs';
|
|
4
4
|
|
|
5
5
|
type WpPlaceholderComponents = Record<string, ComponentType<Record<string, unknown>>>;
|
|
6
6
|
interface WpContentProps {
|
package/dist/react.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
|
-
import { W as WpContentPart } from './types-
|
|
3
|
+
import { W as WpContentPart } from './types-B9QucQ0W.js';
|
|
4
4
|
|
|
5
5
|
type WpPlaceholderComponents = Record<string, ComponentType<Record<string, unknown>>>;
|
|
6
6
|
interface WpContentProps {
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
interface WpRenderedField {
|
|
2
|
+
rendered: string;
|
|
3
|
+
}
|
|
4
|
+
interface WpFeaturedMedia {
|
|
5
|
+
source_url?: string;
|
|
6
|
+
}
|
|
7
|
+
interface WpTerm {
|
|
8
|
+
id: number;
|
|
9
|
+
slug?: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
taxonomy?: string;
|
|
12
|
+
count?: number;
|
|
13
|
+
}
|
|
14
|
+
interface WpAuthor {
|
|
15
|
+
id: number;
|
|
16
|
+
name?: string;
|
|
17
|
+
slug?: string;
|
|
18
|
+
url?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
link?: string;
|
|
21
|
+
avatar_urls?: Record<string, string>;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
interface WpEmbedded {
|
|
25
|
+
"wp:featuredmedia"?: WpFeaturedMedia[];
|
|
26
|
+
"wp:term"?: WpTerm[][];
|
|
27
|
+
author?: WpAuthor[];
|
|
28
|
+
}
|
|
29
|
+
interface WpPost {
|
|
30
|
+
id: number;
|
|
31
|
+
slug: string;
|
|
32
|
+
link: string;
|
|
33
|
+
date: string;
|
|
34
|
+
modified: string;
|
|
35
|
+
title: WpRenderedField;
|
|
36
|
+
excerpt: WpRenderedField;
|
|
37
|
+
content: WpRenderedField;
|
|
38
|
+
_embedded?: WpEmbedded;
|
|
39
|
+
}
|
|
40
|
+
interface LinkRewriteContext {
|
|
41
|
+
href: string;
|
|
42
|
+
pathname: string;
|
|
43
|
+
search: string;
|
|
44
|
+
hash: string;
|
|
45
|
+
}
|
|
46
|
+
interface LinkRewriteRule {
|
|
47
|
+
source: string;
|
|
48
|
+
destination?: string;
|
|
49
|
+
action?: "ignore";
|
|
50
|
+
transform?: (context: LinkRewriteContext) => string;
|
|
51
|
+
}
|
|
52
|
+
type ClassNameMapMode = "append" | "replace" | "replace-all";
|
|
53
|
+
interface ClassNameMapRule {
|
|
54
|
+
className: string;
|
|
55
|
+
mode?: ClassNameMapMode;
|
|
56
|
+
}
|
|
57
|
+
type ClassNameMapValue = string | ClassNameMapRule;
|
|
58
|
+
type ClassNameMap = Record<string, ClassNameMapValue>;
|
|
59
|
+
type PlaceholderProps = Record<string, unknown>;
|
|
60
|
+
interface HtmlContentPart {
|
|
61
|
+
type: "html";
|
|
62
|
+
html: string;
|
|
63
|
+
}
|
|
64
|
+
interface PlaceholderContentPart {
|
|
65
|
+
type: "placeholder";
|
|
66
|
+
name: string;
|
|
67
|
+
props: PlaceholderProps;
|
|
68
|
+
}
|
|
69
|
+
type WpContentPart = HtmlContentPart | PlaceholderContentPart;
|
|
70
|
+
interface PlaceholderParseOptions {
|
|
71
|
+
namespace?: string;
|
|
72
|
+
maxPropsLength?: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Normalized post shape returned by this package.
|
|
76
|
+
*/
|
|
77
|
+
interface BlogPostSummary {
|
|
78
|
+
id: number;
|
|
79
|
+
slug: string;
|
|
80
|
+
url: string;
|
|
81
|
+
date: string;
|
|
82
|
+
modified: string;
|
|
83
|
+
publishedDate: string;
|
|
84
|
+
updatedDate: string;
|
|
85
|
+
title: string;
|
|
86
|
+
excerpt: string;
|
|
87
|
+
featuredImageUrl: string | null;
|
|
88
|
+
author: BlogAuthor | null;
|
|
89
|
+
categories: BlogTerm[];
|
|
90
|
+
tags: BlogTerm[];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Full post shape returned by single-post methods.
|
|
94
|
+
*/
|
|
95
|
+
interface BlogPost extends BlogPostSummary {
|
|
96
|
+
contentHtml: string;
|
|
97
|
+
}
|
|
98
|
+
interface BlogTerm {
|
|
99
|
+
id: number;
|
|
100
|
+
slug: string;
|
|
101
|
+
name: string;
|
|
102
|
+
count: number;
|
|
103
|
+
}
|
|
104
|
+
type BlogAuthor = WpAuthor;
|
|
105
|
+
type BlogTermOrder = "default" | "alphabetical" | "count";
|
|
106
|
+
interface GetTermsParams {
|
|
107
|
+
order?: BlogTermOrder;
|
|
108
|
+
}
|
|
109
|
+
interface GetAuthorsParams {
|
|
110
|
+
page?: number;
|
|
111
|
+
perPage?: number;
|
|
112
|
+
}
|
|
113
|
+
type BlogTextMode = "plain" | "html";
|
|
114
|
+
type BlogPostSummaryField = keyof BlogPostSummary;
|
|
115
|
+
type BlogPostField = keyof BlogPost;
|
|
116
|
+
type SelectFields<T, TSelect extends readonly (keyof T)[] | undefined> = TSelect extends readonly (keyof T)[] ? Pick<T, TSelect[number]> : T;
|
|
117
|
+
/**
|
|
118
|
+
* Pagination metadata returned from list endpoints.
|
|
119
|
+
*/
|
|
120
|
+
interface PaginationMeta {
|
|
121
|
+
page: number;
|
|
122
|
+
perPage: number;
|
|
123
|
+
totalItems: number;
|
|
124
|
+
totalPages: number;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Response returned by getPosts.
|
|
128
|
+
*/
|
|
129
|
+
interface PostListResult<TItem = BlogPostSummary> {
|
|
130
|
+
items: TItem[];
|
|
131
|
+
pagination: PaginationMeta;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Optional pagination parameters for getPosts.
|
|
135
|
+
*/
|
|
136
|
+
interface GetPostsParams<TSelect extends readonly BlogPostSummaryField[] | undefined = undefined> {
|
|
137
|
+
page?: number;
|
|
138
|
+
perPage?: number;
|
|
139
|
+
status?: "draft" | "private" | "publish" | "any";
|
|
140
|
+
categorySlug?: string;
|
|
141
|
+
tagSlug?: string;
|
|
142
|
+
textMode?: BlogTextMode;
|
|
143
|
+
select?: TSelect;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parameters for searching published posts.
|
|
147
|
+
*/
|
|
148
|
+
interface SearchPostsParams<TSelect extends readonly BlogPostSummaryField[] | undefined = undefined> extends GetPostsParams<TSelect> {
|
|
149
|
+
query: string;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Options for creating an explicit WordPress client.
|
|
153
|
+
*/
|
|
154
|
+
interface WpClientOptions {
|
|
155
|
+
wpUrl?: string;
|
|
156
|
+
endpoint?: string;
|
|
157
|
+
perPage?: number;
|
|
158
|
+
auth?: WpAuthConfig;
|
|
159
|
+
rewriteLinks?: LinkRewriteRule[];
|
|
160
|
+
classNameMap?: ClassNameMap;
|
|
161
|
+
transformPostContentHtml?: (html: string) => string;
|
|
162
|
+
fetchImpl?: typeof fetch;
|
|
163
|
+
requestInit?: RequestInit;
|
|
164
|
+
}
|
|
165
|
+
type WpAuthType = "none" | "basic" | "bearer" | "headers";
|
|
166
|
+
interface WpAuthConfig {
|
|
167
|
+
type?: WpAuthType;
|
|
168
|
+
user?: string;
|
|
169
|
+
appPassword?: string;
|
|
170
|
+
token?: string;
|
|
171
|
+
headers?: Record<string, string>;
|
|
172
|
+
}
|
|
173
|
+
interface WpAuthResolvedConfig {
|
|
174
|
+
type: WpAuthType;
|
|
175
|
+
user?: string;
|
|
176
|
+
appPassword?: string;
|
|
177
|
+
token?: string;
|
|
178
|
+
headers?: Record<string, string>;
|
|
179
|
+
}
|
|
180
|
+
interface GetPostParams<TSelect extends readonly BlogPostField[] | undefined = undefined> {
|
|
181
|
+
status?: "draft" | "private" | "publish" | "any";
|
|
182
|
+
textMode?: BlogTextMode;
|
|
183
|
+
select?: TSelect;
|
|
184
|
+
}
|
|
185
|
+
interface QueryRawRestInput {
|
|
186
|
+
path: string;
|
|
187
|
+
params?: Record<string, string | number | boolean | null | undefined>;
|
|
188
|
+
method?: string;
|
|
189
|
+
body?: unknown;
|
|
190
|
+
headers?: Record<string, string>;
|
|
191
|
+
}
|
|
192
|
+
interface QueryRawParams {
|
|
193
|
+
rest?: QueryRawRestInput;
|
|
194
|
+
authRequired?: boolean;
|
|
195
|
+
}
|
|
196
|
+
interface QueryGraphqlParams {
|
|
197
|
+
query: string;
|
|
198
|
+
variables?: Record<string, unknown>;
|
|
199
|
+
}
|
|
200
|
+
interface QueryGraphqlResult<TData = unknown> {
|
|
201
|
+
data?: TData;
|
|
202
|
+
errors?: Array<Record<string, unknown>>;
|
|
203
|
+
}
|
|
204
|
+
interface WpBlogClient {
|
|
205
|
+
/**
|
|
206
|
+
* Fetches a page of published WordPress posts.
|
|
207
|
+
*/
|
|
208
|
+
getPosts<TSelect extends readonly BlogPostSummaryField[] | undefined = undefined>(params?: GetPostsParams<TSelect>): Promise<PostListResult<SelectFields<BlogPostSummary, TSelect>>>;
|
|
209
|
+
/**
|
|
210
|
+
* Searches posts using the WordPress REST search parameter.
|
|
211
|
+
*/
|
|
212
|
+
searchPosts<TSelect extends readonly BlogPostSummaryField[] | undefined = undefined>(params: SearchPostsParams<TSelect>): Promise<PostListResult<SelectFields<BlogPostSummary, TSelect>>>;
|
|
213
|
+
/**
|
|
214
|
+
* Fetches a single post by slug, or null when not found.
|
|
215
|
+
*/
|
|
216
|
+
getPostBySlug<TSelect extends readonly BlogPostField[] | undefined = undefined>(slug: string, params?: GetPostParams<TSelect>): Promise<SelectFields<BlogPost, TSelect> | null>;
|
|
217
|
+
/**
|
|
218
|
+
* Fetches a single published post by WordPress post ID, or null when not found.
|
|
219
|
+
*/
|
|
220
|
+
getPostById<TSelect extends readonly BlogPostField[] | undefined = undefined>(id: number, params?: GetPostParams<TSelect>): Promise<SelectFields<BlogPost, TSelect> | null>;
|
|
221
|
+
/**
|
|
222
|
+
* Executes a raw request against REST for custom fields/shapes.
|
|
223
|
+
* Use this as an escape hatch for custom fields/shapes.
|
|
224
|
+
*/
|
|
225
|
+
queryRaw<TData = unknown>(params: QueryRawParams): Promise<TData>;
|
|
226
|
+
/**
|
|
227
|
+
* Executes a raw GraphQL request.
|
|
228
|
+
* Uses WP_URL + endpoint and existing WP_AUTH_* auth config.
|
|
229
|
+
*/
|
|
230
|
+
queryGraphql<TData = unknown>(params: QueryGraphqlParams): Promise<QueryGraphqlResult<TData>>;
|
|
231
|
+
/**
|
|
232
|
+
* Fetches blog categories for archive navigation/sidebars.
|
|
233
|
+
*/
|
|
234
|
+
getCategories(params?: GetTermsParams): Promise<BlogTerm[]>;
|
|
235
|
+
/**
|
|
236
|
+
* Fetches blog tags for archive navigation/sidebars.
|
|
237
|
+
*/
|
|
238
|
+
getTags(params?: GetTermsParams): Promise<BlogTerm[]>;
|
|
239
|
+
/**
|
|
240
|
+
* Fetches a page of WordPress authors.
|
|
241
|
+
*/
|
|
242
|
+
getAuthors(params?: GetAuthorsParams): Promise<BlogAuthor[]>;
|
|
243
|
+
/**
|
|
244
|
+
* Fetches a single WordPress author by ID.
|
|
245
|
+
*/
|
|
246
|
+
getAuthorById(id: number): Promise<BlogAuthor | null>;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export type { WpAuthResolvedConfig as A, BlogTerm as B, ClassNameMap as C, WpAuthType as D, WpEmbedded as E, WpFeaturedMedia as F, GetAuthorsParams as G, HtmlContentPart as H, WpPost as I, WpRenderedField as J, WpTerm as K, LinkRewriteContext as L, PlaceholderParseOptions as P, QueryGraphqlParams as Q, SelectFields as S, WpContentPart as W, WpClientOptions as a, WpBlogClient as b, WpAuthor as c, GetTermsParams as d, BlogPostField as e, GetPostParams as f, BlogPost as g, BlogPostSummaryField as h, GetPostsParams as i, PostListResult as j, BlogPostSummary as k, QueryGraphqlResult as l, QueryRawParams as m, SearchPostsParams as n, BlogAuthor as o, BlogTermOrder as p, BlogTextMode as q, ClassNameMapMode as r, ClassNameMapRule as s, ClassNameMapValue as t, LinkRewriteRule as u, PaginationMeta as v, PlaceholderContentPart as w, PlaceholderProps as x, QueryRawRestInput as y, WpAuthConfig as z };
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
interface WpRenderedField {
|
|
2
|
+
rendered: string;
|
|
3
|
+
}
|
|
4
|
+
interface WpFeaturedMedia {
|
|
5
|
+
source_url?: string;
|
|
6
|
+
}
|
|
7
|
+
interface WpTerm {
|
|
8
|
+
id: number;
|
|
9
|
+
slug?: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
taxonomy?: string;
|
|
12
|
+
count?: number;
|
|
13
|
+
}
|
|
14
|
+
interface WpAuthor {
|
|
15
|
+
id: number;
|
|
16
|
+
name?: string;
|
|
17
|
+
slug?: string;
|
|
18
|
+
url?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
link?: string;
|
|
21
|
+
avatar_urls?: Record<string, string>;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
interface WpEmbedded {
|
|
25
|
+
"wp:featuredmedia"?: WpFeaturedMedia[];
|
|
26
|
+
"wp:term"?: WpTerm[][];
|
|
27
|
+
author?: WpAuthor[];
|
|
28
|
+
}
|
|
29
|
+
interface WpPost {
|
|
30
|
+
id: number;
|
|
31
|
+
slug: string;
|
|
32
|
+
link: string;
|
|
33
|
+
date: string;
|
|
34
|
+
modified: string;
|
|
35
|
+
title: WpRenderedField;
|
|
36
|
+
excerpt: WpRenderedField;
|
|
37
|
+
content: WpRenderedField;
|
|
38
|
+
_embedded?: WpEmbedded;
|
|
39
|
+
}
|
|
40
|
+
interface LinkRewriteContext {
|
|
41
|
+
href: string;
|
|
42
|
+
pathname: string;
|
|
43
|
+
search: string;
|
|
44
|
+
hash: string;
|
|
45
|
+
}
|
|
46
|
+
interface LinkRewriteRule {
|
|
47
|
+
source: string;
|
|
48
|
+
destination?: string;
|
|
49
|
+
action?: "ignore";
|
|
50
|
+
transform?: (context: LinkRewriteContext) => string;
|
|
51
|
+
}
|
|
52
|
+
type ClassNameMapMode = "append" | "replace" | "replace-all";
|
|
53
|
+
interface ClassNameMapRule {
|
|
54
|
+
className: string;
|
|
55
|
+
mode?: ClassNameMapMode;
|
|
56
|
+
}
|
|
57
|
+
type ClassNameMapValue = string | ClassNameMapRule;
|
|
58
|
+
type ClassNameMap = Record<string, ClassNameMapValue>;
|
|
59
|
+
type PlaceholderProps = Record<string, unknown>;
|
|
60
|
+
interface HtmlContentPart {
|
|
61
|
+
type: "html";
|
|
62
|
+
html: string;
|
|
63
|
+
}
|
|
64
|
+
interface PlaceholderContentPart {
|
|
65
|
+
type: "placeholder";
|
|
66
|
+
name: string;
|
|
67
|
+
props: PlaceholderProps;
|
|
68
|
+
}
|
|
69
|
+
type WpContentPart = HtmlContentPart | PlaceholderContentPart;
|
|
70
|
+
interface PlaceholderParseOptions {
|
|
71
|
+
namespace?: string;
|
|
72
|
+
maxPropsLength?: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Normalized post shape returned by this package.
|
|
76
|
+
*/
|
|
77
|
+
interface BlogPostSummary {
|
|
78
|
+
id: number;
|
|
79
|
+
slug: string;
|
|
80
|
+
url: string;
|
|
81
|
+
date: string;
|
|
82
|
+
modified: string;
|
|
83
|
+
publishedDate: string;
|
|
84
|
+
updatedDate: string;
|
|
85
|
+
title: string;
|
|
86
|
+
excerpt: string;
|
|
87
|
+
featuredImageUrl: string | null;
|
|
88
|
+
author: BlogAuthor | null;
|
|
89
|
+
categories: BlogTerm[];
|
|
90
|
+
tags: BlogTerm[];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Full post shape returned by single-post methods.
|
|
94
|
+
*/
|
|
95
|
+
interface BlogPost extends BlogPostSummary {
|
|
96
|
+
contentHtml: string;
|
|
97
|
+
}
|
|
98
|
+
interface BlogTerm {
|
|
99
|
+
id: number;
|
|
100
|
+
slug: string;
|
|
101
|
+
name: string;
|
|
102
|
+
count: number;
|
|
103
|
+
}
|
|
104
|
+
type BlogAuthor = WpAuthor;
|
|
105
|
+
type BlogTermOrder = "default" | "alphabetical" | "count";
|
|
106
|
+
interface GetTermsParams {
|
|
107
|
+
order?: BlogTermOrder;
|
|
108
|
+
}
|
|
109
|
+
interface GetAuthorsParams {
|
|
110
|
+
page?: number;
|
|
111
|
+
perPage?: number;
|
|
112
|
+
}
|
|
113
|
+
type BlogTextMode = "plain" | "html";
|
|
114
|
+
type BlogPostSummaryField = keyof BlogPostSummary;
|
|
115
|
+
type BlogPostField = keyof BlogPost;
|
|
116
|
+
type SelectFields<T, TSelect extends readonly (keyof T)[] | undefined> = TSelect extends readonly (keyof T)[] ? Pick<T, TSelect[number]> : T;
|
|
117
|
+
/**
|
|
118
|
+
* Pagination metadata returned from list endpoints.
|
|
119
|
+
*/
|
|
120
|
+
interface PaginationMeta {
|
|
121
|
+
page: number;
|
|
122
|
+
perPage: number;
|
|
123
|
+
totalItems: number;
|
|
124
|
+
totalPages: number;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Response returned by getPosts.
|
|
128
|
+
*/
|
|
129
|
+
interface PostListResult<TItem = BlogPostSummary> {
|
|
130
|
+
items: TItem[];
|
|
131
|
+
pagination: PaginationMeta;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Optional pagination parameters for getPosts.
|
|
135
|
+
*/
|
|
136
|
+
interface GetPostsParams<TSelect extends readonly BlogPostSummaryField[] | undefined = undefined> {
|
|
137
|
+
page?: number;
|
|
138
|
+
perPage?: number;
|
|
139
|
+
status?: "draft" | "private" | "publish" | "any";
|
|
140
|
+
categorySlug?: string;
|
|
141
|
+
tagSlug?: string;
|
|
142
|
+
textMode?: BlogTextMode;
|
|
143
|
+
select?: TSelect;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parameters for searching published posts.
|
|
147
|
+
*/
|
|
148
|
+
interface SearchPostsParams<TSelect extends readonly BlogPostSummaryField[] | undefined = undefined> extends GetPostsParams<TSelect> {
|
|
149
|
+
query: string;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Options for creating an explicit WordPress client.
|
|
153
|
+
*/
|
|
154
|
+
interface WpClientOptions {
|
|
155
|
+
wpUrl?: string;
|
|
156
|
+
endpoint?: string;
|
|
157
|
+
perPage?: number;
|
|
158
|
+
auth?: WpAuthConfig;
|
|
159
|
+
rewriteLinks?: LinkRewriteRule[];
|
|
160
|
+
classNameMap?: ClassNameMap;
|
|
161
|
+
transformPostContentHtml?: (html: string) => string;
|
|
162
|
+
fetchImpl?: typeof fetch;
|
|
163
|
+
requestInit?: RequestInit;
|
|
164
|
+
}
|
|
165
|
+
type WpAuthType = "none" | "basic" | "bearer" | "headers";
|
|
166
|
+
interface WpAuthConfig {
|
|
167
|
+
type?: WpAuthType;
|
|
168
|
+
user?: string;
|
|
169
|
+
appPassword?: string;
|
|
170
|
+
token?: string;
|
|
171
|
+
headers?: Record<string, string>;
|
|
172
|
+
}
|
|
173
|
+
interface WpAuthResolvedConfig {
|
|
174
|
+
type: WpAuthType;
|
|
175
|
+
user?: string;
|
|
176
|
+
appPassword?: string;
|
|
177
|
+
token?: string;
|
|
178
|
+
headers?: Record<string, string>;
|
|
179
|
+
}
|
|
180
|
+
interface GetPostParams<TSelect extends readonly BlogPostField[] | undefined = undefined> {
|
|
181
|
+
status?: "draft" | "private" | "publish" | "any";
|
|
182
|
+
textMode?: BlogTextMode;
|
|
183
|
+
select?: TSelect;
|
|
184
|
+
}
|
|
185
|
+
interface QueryRawRestInput {
|
|
186
|
+
path: string;
|
|
187
|
+
params?: Record<string, string | number | boolean | null | undefined>;
|
|
188
|
+
method?: string;
|
|
189
|
+
body?: unknown;
|
|
190
|
+
headers?: Record<string, string>;
|
|
191
|
+
}
|
|
192
|
+
interface QueryRawParams {
|
|
193
|
+
rest?: QueryRawRestInput;
|
|
194
|
+
authRequired?: boolean;
|
|
195
|
+
}
|
|
196
|
+
interface QueryGraphqlParams {
|
|
197
|
+
query: string;
|
|
198
|
+
variables?: Record<string, unknown>;
|
|
199
|
+
}
|
|
200
|
+
interface QueryGraphqlResult<TData = unknown> {
|
|
201
|
+
data?: TData;
|
|
202
|
+
errors?: Array<Record<string, unknown>>;
|
|
203
|
+
}
|
|
204
|
+
interface WpBlogClient {
|
|
205
|
+
/**
|
|
206
|
+
* Fetches a page of published WordPress posts.
|
|
207
|
+
*/
|
|
208
|
+
getPosts<TSelect extends readonly BlogPostSummaryField[] | undefined = undefined>(params?: GetPostsParams<TSelect>): Promise<PostListResult<SelectFields<BlogPostSummary, TSelect>>>;
|
|
209
|
+
/**
|
|
210
|
+
* Searches posts using the WordPress REST search parameter.
|
|
211
|
+
*/
|
|
212
|
+
searchPosts<TSelect extends readonly BlogPostSummaryField[] | undefined = undefined>(params: SearchPostsParams<TSelect>): Promise<PostListResult<SelectFields<BlogPostSummary, TSelect>>>;
|
|
213
|
+
/**
|
|
214
|
+
* Fetches a single post by slug, or null when not found.
|
|
215
|
+
*/
|
|
216
|
+
getPostBySlug<TSelect extends readonly BlogPostField[] | undefined = undefined>(slug: string, params?: GetPostParams<TSelect>): Promise<SelectFields<BlogPost, TSelect> | null>;
|
|
217
|
+
/**
|
|
218
|
+
* Fetches a single published post by WordPress post ID, or null when not found.
|
|
219
|
+
*/
|
|
220
|
+
getPostById<TSelect extends readonly BlogPostField[] | undefined = undefined>(id: number, params?: GetPostParams<TSelect>): Promise<SelectFields<BlogPost, TSelect> | null>;
|
|
221
|
+
/**
|
|
222
|
+
* Executes a raw request against REST for custom fields/shapes.
|
|
223
|
+
* Use this as an escape hatch for custom fields/shapes.
|
|
224
|
+
*/
|
|
225
|
+
queryRaw<TData = unknown>(params: QueryRawParams): Promise<TData>;
|
|
226
|
+
/**
|
|
227
|
+
* Executes a raw GraphQL request.
|
|
228
|
+
* Uses WP_URL + endpoint and existing WP_AUTH_* auth config.
|
|
229
|
+
*/
|
|
230
|
+
queryGraphql<TData = unknown>(params: QueryGraphqlParams): Promise<QueryGraphqlResult<TData>>;
|
|
231
|
+
/**
|
|
232
|
+
* Fetches blog categories for archive navigation/sidebars.
|
|
233
|
+
*/
|
|
234
|
+
getCategories(params?: GetTermsParams): Promise<BlogTerm[]>;
|
|
235
|
+
/**
|
|
236
|
+
* Fetches blog tags for archive navigation/sidebars.
|
|
237
|
+
*/
|
|
238
|
+
getTags(params?: GetTermsParams): Promise<BlogTerm[]>;
|
|
239
|
+
/**
|
|
240
|
+
* Fetches a page of WordPress authors.
|
|
241
|
+
*/
|
|
242
|
+
getAuthors(params?: GetAuthorsParams): Promise<BlogAuthor[]>;
|
|
243
|
+
/**
|
|
244
|
+
* Fetches a single WordPress author by ID.
|
|
245
|
+
*/
|
|
246
|
+
getAuthorById(id: number): Promise<BlogAuthor | null>;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export type { WpAuthResolvedConfig as A, BlogTerm as B, ClassNameMap as C, WpAuthType as D, WpEmbedded as E, WpFeaturedMedia as F, GetAuthorsParams as G, HtmlContentPart as H, WpPost as I, WpRenderedField as J, WpTerm as K, LinkRewriteContext as L, PlaceholderParseOptions as P, QueryGraphqlParams as Q, SelectFields as S, WpContentPart as W, WpClientOptions as a, WpBlogClient as b, WpAuthor as c, GetTermsParams as d, BlogPostField as e, GetPostParams as f, BlogPost as g, BlogPostSummaryField as h, GetPostsParams as i, PostListResult as j, BlogPostSummary as k, QueryGraphqlResult as l, QueryRawParams as m, SearchPostsParams as n, BlogAuthor as o, BlogTermOrder as p, BlogTextMode as q, ClassNameMapMode as r, ClassNameMapRule as s, ClassNameMapValue as t, LinkRewriteRule as u, PaginationMeta as v, PlaceholderContentPart as w, PlaceholderProps as x, QueryRawRestInput as y, WpAuthConfig as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@readpress/wp-blog",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "A minimal, read-only headless WordPress blog adapter for modern web apps",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "tsup",
|
|
25
25
|
"prepack": "npm run build",
|
|
26
|
+
"check:publish-version": "node scripts/check-publish-version.mjs",
|
|
27
|
+
"prepublishOnly": "npm run check:publish-version",
|
|
26
28
|
"test": "npm run build && node --test test/*.test.mjs",
|
|
27
29
|
"docs:api": "typedoc",
|
|
28
30
|
"docs:api:clean": "rm -rf docs/reference && typedoc"
|