@mailoo/blog 0.0.0-stage → 1.33.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 +16 -0
- package/README.md +142 -2
- package/dist/client/article-body.cjs +115 -0
- package/dist/client/article-body.cjs.map +1 -0
- package/dist/client/article-body.d.cts +15 -0
- package/dist/client/article-body.d.ts +15 -0
- package/dist/client/article-body.js +80 -0
- package/dist/client/article-body.js.map +1 -0
- package/dist/client/index.cjs +776 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.cts +6 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +731 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/linked-links.cjs +125 -0
- package/dist/client/linked-links.cjs.map +1 -0
- package/dist/client/linked-links.d.cts +31 -0
- package/dist/client/linked-links.d.ts +31 -0
- package/dist/client/linked-links.js +100 -0
- package/dist/client/linked-links.js.map +1 -0
- package/dist/client/marks.cjs +300 -0
- package/dist/client/marks.cjs.map +1 -0
- package/dist/client/marks.d.cts +30 -0
- package/dist/client/marks.d.ts +30 -0
- package/dist/client/marks.js +276 -0
- package/dist/client/marks.js.map +1 -0
- package/dist/client/printable.cjs +106 -0
- package/dist/client/printable.cjs.map +1 -0
- package/dist/client/printable.d.cts +12 -0
- package/dist/client/printable.d.ts +12 -0
- package/dist/client/printable.js +82 -0
- package/dist/client/printable.js.map +1 -0
- package/dist/client/share.cjs +234 -0
- package/dist/client/share.cjs.map +1 -0
- package/dist/client/share.d.cts +41 -0
- package/dist/client/share.d.ts +41 -0
- package/dist/client/share.js +205 -0
- package/dist/client/share.js.map +1 -0
- package/dist/index.cjs +89 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/routes/index.cjs +266 -0
- package/dist/routes/index.cjs.map +1 -0
- package/dist/routes/index.d.cts +87 -0
- package/dist/routes/index.d.ts +87 -0
- package/dist/routes/index.js +240 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/server/index.cjs +368 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +132 -0
- package/dist/server/index.d.ts +132 -0
- package/dist/server/index.js +339 -0
- package/dist/server/index.js.map +1 -0
- package/dist/utils-DXbN9MTi.d.cts +120 -0
- package/dist/utils-DXbN9MTi.d.ts +120 -0
- package/package.json +110 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/server/client.ts","../../src/server/fetch-bff.ts","../../src/server/utils.ts"],"sourcesContent":["import { unstable_rethrow } from 'next/navigation'\nimport type { MailooIntegrationConfig } from '@mailoo/next-core'\nimport { readMailooIntegrationConfig } from '@mailoo/next-core'\nimport {\n rewriteMailooBlogMediaUrls,\n rewriteMailooPublicImageUrls,\n rewriteMailooPublicImageUrlsAnyHost,\n} from '@mailoo/images'\nimport type {\n BlogArticleMarkState,\n BlogCategoryApi,\n BlogTagApi,\n BlogListPagination,\n BlogListQuery,\n BlogPostApiData,\n MailooBlogFetchOptions,\n SetBlogFeedbackInput,\n SetBlogReactionInput,\n} from '../types.js'\n\nexport type MailooBlogConfig = MailooIntegrationConfig\nexport type { MailooBlogFetchOptions }\n\n/** Host image proxy. Omit to keep canonical Mailoo embed URLs. */\nexport type CreateMailooBlogClientOptions = {\n /**\n * Integrator prefix ending with `?id=` (absolute or same-origin path).\n * Example: `/api/v1/images/public/content?id=`\n */\n imageProxyPrefixWithIdEquals?: string\n}\n\nconst DEFAULT_REVALIDATE = 60\n\n/** Read MAILOO_BLOG_* env (API, API_KEY, PROJECT_UID, INTEGRATION_ID). */\nexport function getMailooBlogConfigFromEnv(): MailooBlogConfig | null {\n return readMailooIntegrationConfig({ prefix: 'MAILOO_BLOG' })\n}\n\nfunction blogBasePath(config: MailooBlogConfig): string {\n return `${config.apiBaseUrl}/api/v1/blog/${config.projectUid}/integrations/${config.integrationId}`\n}\n\nfunction resolveRevalidate(options?: MailooBlogFetchOptions): number {\n return options?.revalidate ?? DEFAULT_REVALIDATE\n}\n\nasync function blogFetchJson(\n config: MailooBlogConfig,\n path: string,\n query?: Record<string, string | undefined>,\n options?: MailooBlogFetchOptions\n): Promise<\n { ok: true; json: unknown; status: number } | { ok: false; status: number }\n> {\n const url = new URL(`${blogBasePath(config)}${path}`)\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v !== undefined && v !== '') url.searchParams.set(k, v)\n }\n }\n try {\n const revalidate = resolveRevalidate(options)\n const res = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': config.apiKey,\n },\n next: { revalidate },\n } as RequestInit)\n if (!res.ok) {\n return { ok: false, status: res.status }\n }\n return { ok: true, json: await res.json(), status: res.status }\n } catch (error) {\n unstable_rethrow(error)\n return { ok: false, status: 500 }\n }\n}\n\nasync function blogPostJson(\n config: MailooBlogConfig,\n path: string,\n body: unknown\n): Promise<\n | { ok: true; data: BlogArticleMarkState; status: number }\n | { ok: false; status: number }\n> {\n try {\n const res = await fetch(`${blogBasePath(config)}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': config.apiKey,\n },\n body: JSON.stringify(body),\n cache: 'no-store',\n })\n if (!res.ok) {\n return { ok: false, status: res.status }\n }\n const json = (await res.json()) as { data?: BlogArticleMarkState }\n if (!json.data || typeof json.data !== 'object') {\n return { ok: false, status: 500 }\n }\n return { ok: true, data: json.data, status: res.status }\n } catch (error) {\n unstable_rethrow(error)\n return { ok: false, status: 500 }\n }\n}\n\nasync function blogGet<T>(\n config: MailooBlogConfig,\n path: string,\n query?: Record<string, string | undefined>,\n options?: MailooBlogFetchOptions\n): Promise<\n { ok: true; data: T; status: number } | { ok: false; status: number }\n> {\n const fetched = await blogFetchJson(config, path, query, options)\n if (!fetched.ok) return fetched\n const json = fetched.json as { data?: T } & T\n const data =\n (json as { data?: T }).data !== undefined\n ? (json as { data: T }).data\n : (json as T)\n return { ok: true, data, status: fetched.status }\n}\n\nfunction isBlogListPagination(value: unknown): value is BlogListPagination {\n if (value === null || typeof value !== 'object') return false\n const p = value as Record<string, unknown>\n return (\n typeof p.page === 'number' &&\n typeof p.limit === 'number' &&\n typeof p.total === 'number' &&\n typeof p.totalPages === 'number' &&\n typeof p.hasNextPage === 'boolean' &&\n typeof p.hasPrevPage === 'boolean'\n )\n}\n\nfunction queryRecord(query: BlogListQuery): Record<string, string | undefined> {\n const q: Record<string, string | undefined> = {}\n for (const [k, v] of Object.entries(query)) {\n if (v === undefined) continue\n q[k] = String(v)\n }\n return q\n}\n\nfunction imageProxyPrefix(\n options?: CreateMailooBlogClientOptions\n): string | undefined {\n const raw = options?.imageProxyPrefixWithIdEquals?.trim()\n return raw || undefined\n}\n\nfunction rewritePost(\n post: BlogPostApiData,\n canonicalPrefixWithIdEquals: string,\n proxyPrefixWithIdEquals: string\n): BlogPostApiData {\n return rewriteMailooBlogMediaUrls(post, {\n canonicalPrefixWithIdEquals,\n proxyPrefixWithIdEquals,\n })\n}\n\ntype CategoryDescription = {\n description?: string\n descriptionHtml?: string\n imagePublicEmbedBaseUrl?: string\n}\n\nexport function createMailooBlogClient(\n config: MailooBlogConfig,\n clientOptions?: CreateMailooBlogClientOptions\n) {\n const proxyPrefix = imageProxyPrefix(clientOptions)\n return {\n async listPosts(\n query: BlogListQuery = {},\n options?: MailooBlogFetchOptions\n ): Promise<\n | {\n ok: true\n data: BlogPostApiData[]\n pagination: BlogListPagination\n imagePublicEmbedBaseUrl: string\n status: number\n }\n | { ok: false; status: number }\n > {\n const fetched = await blogFetchJson(\n config,\n '',\n queryRecord(query),\n options\n )\n if (!fetched.ok) return fetched\n const json = fetched.json\n if (json === null || typeof json !== 'object') {\n return { ok: false, status: 500 }\n }\n const body = json as {\n data?: unknown\n pagination?: unknown\n imagePublicEmbedBaseUrl?: unknown\n }\n const imagePublicEmbedBaseUrl =\n typeof body.imagePublicEmbedBaseUrl === 'string'\n ? body.imagePublicEmbedBaseUrl.trim()\n : ''\n if (\n !Array.isArray(body.data) ||\n !isBlogListPagination(body.pagination) ||\n !imagePublicEmbedBaseUrl\n ) {\n return { ok: false, status: 500 }\n }\n const posts = body.data as BlogPostApiData[]\n return {\n ok: true,\n data: proxyPrefix\n ? posts.map((post) =>\n rewritePost(post, imagePublicEmbedBaseUrl, proxyPrefix)\n )\n : posts,\n pagination: body.pagination,\n imagePublicEmbedBaseUrl,\n status: fetched.status,\n }\n },\n\n async getPostBySlug(\n slug: string,\n locale?: string,\n options?: MailooBlogFetchOptions\n ) {\n const result = await blogGet<BlogPostApiData>(\n config,\n `/slug/${encodeURIComponent(slug)}`,\n locale ? { locale } : undefined,\n options\n )\n if (!result.ok || !proxyPrefix) return result\n const canonical = result.data.imagePublicEmbedBaseUrl?.trim()\n if (!canonical) return { ok: false as const, status: 500 }\n return {\n ...result,\n data: rewritePost(result.data, canonical, proxyPrefix),\n }\n },\n\n async getPostJsonLd(\n slug: string,\n locale?: string,\n options?: MailooBlogFetchOptions\n ) {\n const result = await blogGet<{ jsonLd: Record<string, unknown> }>(\n config,\n `/slug/${encodeURIComponent(slug)}/json-ld`,\n locale ? { locale } : undefined,\n options\n )\n if (!result.ok || !proxyPrefix) return result\n const rewritten = rewriteMailooPublicImageUrlsAnyHost(\n JSON.stringify(result.data.jsonLd),\n proxyPrefix\n )\n try {\n return {\n ...result,\n data: { jsonLd: JSON.parse(rewritten) as Record<string, unknown> },\n }\n } catch {\n return { ok: false as const, status: 500 }\n }\n },\n\n async listCategories(locale?: string, options?: MailooBlogFetchOptions) {\n return blogGet<BlogCategoryApi[]>(\n config,\n '/categories',\n locale ? { locale } : undefined,\n options\n )\n },\n\n async listTags(locale?: string, options?: MailooBlogFetchOptions) {\n return blogGet<BlogTagApi[]>(\n config,\n '/tags',\n locale ? { locale } : undefined,\n options\n )\n },\n\n async getTagBySlug(\n slug: string,\n locale?: string,\n options?: MailooBlogFetchOptions\n ) {\n return blogGet<BlogTagApi>(\n config,\n `/tags/slug/${encodeURIComponent(slug)}`,\n locale ? { locale } : undefined,\n options\n )\n },\n\n async getCategoryDescription(\n slug: string,\n locale?: string,\n options?: MailooBlogFetchOptions\n ) {\n const result = await blogGet<CategoryDescription>(\n config,\n `/categories/slug/${encodeURIComponent(slug)}/description`,\n locale ? { locale } : undefined,\n options\n )\n if (!result.ok || !proxyPrefix) return result\n const canonical = result.data.imagePublicEmbedBaseUrl?.trim()\n if (!canonical) return { ok: false as const, status: 500 }\n const opts = {\n canonicalPrefixWithIdEquals: canonical,\n proxyPrefixWithIdEquals: proxyPrefix,\n }\n return {\n ...result,\n data: {\n ...result.data,\n description:\n typeof result.data.description === 'string'\n ? rewriteMailooPublicImageUrls(result.data.description, opts)\n : result.data.description,\n descriptionHtml:\n typeof result.data.descriptionHtml === 'string'\n ? rewriteMailooPublicImageUrls(result.data.descriptionHtml, opts)\n : result.data.descriptionHtml,\n },\n }\n },\n\n async setReaction(slug: string, input: SetBlogReactionInput) {\n return blogPostJson(\n config,\n `/slug/${encodeURIComponent(slug)}/reaction`,\n input\n )\n },\n\n async setFeedback(slug: string, input: SetBlogFeedbackInput) {\n return blogPostJson(\n config,\n `/slug/${encodeURIComponent(slug)}/feedback`,\n input\n )\n },\n }\n}\n\nexport type MailooBlogClient = ReturnType<typeof createMailooBlogClient>\n","import { unstable_rethrow } from 'next/navigation'\nimport { getRequestOriginBaseUrl } from '@mailoo/next-core/request-origin'\nimport type { BlogPostApiData } from '../types.js'\n\n/**\n * Fetch a blog post via the host app's same-origin BFF\n * (`GET /api/v1/blog/slug/:slug`).\n * Never throws on network / Host / JSON failures — returns `{ ok: false }`.\n */\nexport async function fetchBlogPostBySlug(\n slug: string,\n locale: string,\n options?: { bffBasePath?: string; revalidate?: number }\n): Promise<\n { ok: true; data: BlogPostApiData } | { ok: false; status: number }\n> {\n try {\n const base = await getRequestOriginBaseUrl()\n const bffBase = options?.bffBasePath ?? '/api/v1/blog'\n const revalidate = options?.revalidate ?? 60\n const slugUrl = new URL(\n `${base}${bffBase}/slug/${encodeURIComponent(slug)}`\n )\n if (locale) slugUrl.searchParams.set('locale', locale)\n const res = await fetch(slugUrl.toString(), {\n next: { revalidate },\n } as RequestInit)\n\n if (!res.ok) {\n return { ok: false, status: res.status }\n }\n\n const json = (await res.json()) as { data?: BlogPostApiData }\n const data = json?.data\n if (!data?.id) {\n return { ok: false, status: 404 }\n }\n\n return { ok: true, data }\n } catch (error) {\n unstable_rethrow(error)\n return { ok: false, status: 500 }\n }\n}\n\n/**\n * Fetch BlogPosting JSON-LD via same-origin BFF.\n * Returns null on any failure (never throws).\n */\nexport async function fetchBlogPostJsonLd(\n slug: string,\n locale: string,\n options?: { bffBasePath?: string; revalidate?: number }\n): Promise<Record<string, unknown> | null> {\n try {\n const base = await getRequestOriginBaseUrl()\n const bffBase = options?.bffBasePath ?? '/api/v1/blog'\n const revalidate = options?.revalidate ?? 60\n const url = new URL(\n `${base}${bffBase}/slug/${encodeURIComponent(slug)}/json-ld`\n )\n if (locale) url.searchParams.set('locale', locale)\n const res = await fetch(url.toString(), {\n next: { revalidate },\n } as RequestInit)\n if (!res.ok) return null\n const json = (await res.json()) as {\n data?: { jsonLd?: Record<string, unknown> }\n }\n return json?.data?.jsonLd ?? null\n } catch (error) {\n unstable_rethrow(error)\n return null\n }\n}\n\n/** Replace Mailoo JSON-LD placeholders with site-specific values. */\nexport function applyJsonLdPlaceholders(\n jsonLd: Record<string, unknown>,\n vars: { canonicalUrl: string; origin: string; locale: string }\n): Record<string, unknown> {\n const raw = JSON.stringify(jsonLd)\n if (!raw.includes('{{canonicalUrl}}') && !raw.includes('{{origin}}')) {\n return jsonLd\n }\n const replaced = raw\n .replaceAll('{{canonicalUrl}}', vars.canonicalUrl)\n .replaceAll('{{origin}}', vars.origin)\n .replaceAll('{{locale}}', vars.locale)\n return JSON.parse(replaced) as Record<string, unknown>\n}\n","/**\n * First absolute image URL for OG/Twitter previews: prefer HTML from the API,\n * then markdown image syntax in content.\n */\nconst HTML_IMG_SRC = /<img[^>]+src=[\"']([^\"']+)[\"']/i\nconst MD_IMAGE = /!\\[[^\\]]*]\\(([^)\\s]+)\\)/\n\nfunction normalizeUrl(raw: string): string | null {\n const u = raw.trim()\n if (!u) return null\n if (\n u.startsWith('http://') ||\n u.startsWith('https://') ||\n u.startsWith('/')\n ) {\n return u\n }\n return null\n}\n\nexport function firstEmbedImageUrlFromArticle(\n htmlContent: string | null | undefined,\n markdownContent: string | null | undefined\n): string | null {\n if (htmlContent) {\n const m = htmlContent.match(HTML_IMG_SRC)\n if (m?.[1]) {\n const url = normalizeUrl(m[1])\n if (url) return url\n }\n }\n if (markdownContent) {\n const m = markdownContent.match(MD_IMAGE)\n if (m?.[1]) {\n const url = normalizeUrl(m[1])\n if (url) return url\n }\n }\n return null\n}\n\n/**\n * Default Tailwind Typography class string for article body.\n * Hosts may pass a custom `className` instead.\n */\nexport const BLOG_ARTICLE_PROSE_CLASSNAME = [\n 'prose',\n 'prose-gray',\n 'prose-lg',\n 'max-w-none',\n 'dark:prose-invert',\n 'prose-a:text-blue-600',\n 'hover:prose-a:text-blue-700',\n 'dark:prose-a:text-blue-400',\n 'dark:hover:prose-a:text-blue-300',\n 'prose-blockquote:border-blue-500',\n 'prose-img:rounded-lg',\n 'prose-img:shadow-sm',\n].join(' ')\n"],"mappings":"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","names":["unstable_rethrow"]}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/** Item in `linkedLinks` on slug detail responses (blog external API). */
|
|
2
|
+
interface BlogPostLinkedLinkApi {
|
|
3
|
+
id: string;
|
|
4
|
+
type: 'internal_article' | 'update_announcement' | 'external_resource';
|
|
5
|
+
label: string;
|
|
6
|
+
url: string;
|
|
7
|
+
intro: string | null;
|
|
8
|
+
date: string | null;
|
|
9
|
+
sortOrder: number;
|
|
10
|
+
}
|
|
11
|
+
type BlogPostReactionSentiment = 'LIKE' | 'DISLIKE';
|
|
12
|
+
type BlogArticleMarkCounts = {
|
|
13
|
+
likeCount: number;
|
|
14
|
+
dislikeCount: number;
|
|
15
|
+
feedbackCount: number;
|
|
16
|
+
};
|
|
17
|
+
type BlogArticleMarkState = BlogArticleMarkCounts & {
|
|
18
|
+
sentiment: BlogPostReactionSentiment | null;
|
|
19
|
+
hasFeedback: boolean;
|
|
20
|
+
};
|
|
21
|
+
type SetBlogReactionInput = {
|
|
22
|
+
visitorKey: string;
|
|
23
|
+
action: 'set' | 'clear';
|
|
24
|
+
sentiment?: BlogPostReactionSentiment;
|
|
25
|
+
comment?: string;
|
|
26
|
+
locale?: string;
|
|
27
|
+
};
|
|
28
|
+
type SetBlogFeedbackInput = {
|
|
29
|
+
visitorKey: string;
|
|
30
|
+
action: 'set' | 'clear';
|
|
31
|
+
comment?: string;
|
|
32
|
+
locale?: string;
|
|
33
|
+
};
|
|
34
|
+
/** Raw article payload from BFF / Mailoo blog API */
|
|
35
|
+
interface BlogPostApiData {
|
|
36
|
+
id: string;
|
|
37
|
+
title: string;
|
|
38
|
+
slug: string;
|
|
39
|
+
excerpt?: string | null;
|
|
40
|
+
content: string;
|
|
41
|
+
htmlContent?: string | null;
|
|
42
|
+
publishedAt?: string | null;
|
|
43
|
+
createdAt: string;
|
|
44
|
+
author?: {
|
|
45
|
+
id?: string;
|
|
46
|
+
name?: string | null;
|
|
47
|
+
email?: string | null;
|
|
48
|
+
avatar?: string | null;
|
|
49
|
+
bio?: string | null;
|
|
50
|
+
};
|
|
51
|
+
category?: string | {
|
|
52
|
+
id: string;
|
|
53
|
+
slug: string;
|
|
54
|
+
name: string;
|
|
55
|
+
} | null;
|
|
56
|
+
readTime?: string | null;
|
|
57
|
+
readTimeMinutes?: number | null;
|
|
58
|
+
/** Page visits from external GET slug; not incremented by BFF/MCP reads. */
|
|
59
|
+
accessCount?: number;
|
|
60
|
+
/** Present on slug detail; optional on list. */
|
|
61
|
+
likeCount?: number;
|
|
62
|
+
dislikeCount?: number;
|
|
63
|
+
feedbackCount?: number;
|
|
64
|
+
tags?: BlogTagApi[];
|
|
65
|
+
metaTitle?: string | null;
|
|
66
|
+
metaDescription?: string | null;
|
|
67
|
+
ogImageUrl?: string | null;
|
|
68
|
+
canonicalUrl?: string | null;
|
|
69
|
+
/** Canonical embed prefix (`…/images/public/content?id=`). Not anonymously fetchable. */
|
|
70
|
+
imagePublicEmbedBaseUrl?: string;
|
|
71
|
+
seoWords?: Array<{
|
|
72
|
+
slug: string;
|
|
73
|
+
word: string;
|
|
74
|
+
}>;
|
|
75
|
+
linkedLinks?: BlogPostLinkedLinkApi[];
|
|
76
|
+
}
|
|
77
|
+
interface BlogCategoryApi {
|
|
78
|
+
id: string;
|
|
79
|
+
slug: string;
|
|
80
|
+
name: string;
|
|
81
|
+
}
|
|
82
|
+
interface BlogTagApi {
|
|
83
|
+
slug: string;
|
|
84
|
+
name: string;
|
|
85
|
+
}
|
|
86
|
+
interface BlogListQuery {
|
|
87
|
+
locale?: string;
|
|
88
|
+
limit?: number;
|
|
89
|
+
page?: number;
|
|
90
|
+
categoryId?: string;
|
|
91
|
+
category?: string;
|
|
92
|
+
intentId?: string;
|
|
93
|
+
audienceId?: string;
|
|
94
|
+
seoClusterId?: string;
|
|
95
|
+
tag?: string;
|
|
96
|
+
[key: string]: string | number | undefined;
|
|
97
|
+
}
|
|
98
|
+
/** Pagination sibling on the external blog list envelope. */
|
|
99
|
+
type BlogListPagination = {
|
|
100
|
+
page: number;
|
|
101
|
+
limit: number;
|
|
102
|
+
total: number;
|
|
103
|
+
totalPages: number;
|
|
104
|
+
hasNextPage: boolean;
|
|
105
|
+
hasPrevPage: boolean;
|
|
106
|
+
};
|
|
107
|
+
/** ISR / cache hint for direct Mailoo API fetches (Next.js `fetch`). */
|
|
108
|
+
type MailooBlogFetchOptions = {
|
|
109
|
+
/** Seconds; default 60. Pass 0 to skip ISR. */
|
|
110
|
+
revalidate?: number;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
declare function firstEmbedImageUrlFromArticle(htmlContent: string | null | undefined, markdownContent: string | null | undefined): string | null;
|
|
114
|
+
/**
|
|
115
|
+
* Default Tailwind Typography class string for article body.
|
|
116
|
+
* Hosts may pass a custom `className` instead.
|
|
117
|
+
*/
|
|
118
|
+
declare const BLOG_ARTICLE_PROSE_CLASSNAME: string;
|
|
119
|
+
|
|
120
|
+
export { type BlogPostApiData as B, type MailooBlogFetchOptions as M, type SetBlogReactionInput as S, type BlogPostLinkedLinkApi as a, type BlogCategoryApi as b, type BlogTagApi as c, type BlogListQuery as d, type BlogListPagination as e, type BlogPostReactionSentiment as f, type BlogArticleMarkCounts as g, type BlogArticleMarkState as h, type SetBlogFeedbackInput as i, BLOG_ARTICLE_PROSE_CLASSNAME as j, firstEmbedImageUrlFromArticle as k };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/** Item in `linkedLinks` on slug detail responses (blog external API). */
|
|
2
|
+
interface BlogPostLinkedLinkApi {
|
|
3
|
+
id: string;
|
|
4
|
+
type: 'internal_article' | 'update_announcement' | 'external_resource';
|
|
5
|
+
label: string;
|
|
6
|
+
url: string;
|
|
7
|
+
intro: string | null;
|
|
8
|
+
date: string | null;
|
|
9
|
+
sortOrder: number;
|
|
10
|
+
}
|
|
11
|
+
type BlogPostReactionSentiment = 'LIKE' | 'DISLIKE';
|
|
12
|
+
type BlogArticleMarkCounts = {
|
|
13
|
+
likeCount: number;
|
|
14
|
+
dislikeCount: number;
|
|
15
|
+
feedbackCount: number;
|
|
16
|
+
};
|
|
17
|
+
type BlogArticleMarkState = BlogArticleMarkCounts & {
|
|
18
|
+
sentiment: BlogPostReactionSentiment | null;
|
|
19
|
+
hasFeedback: boolean;
|
|
20
|
+
};
|
|
21
|
+
type SetBlogReactionInput = {
|
|
22
|
+
visitorKey: string;
|
|
23
|
+
action: 'set' | 'clear';
|
|
24
|
+
sentiment?: BlogPostReactionSentiment;
|
|
25
|
+
comment?: string;
|
|
26
|
+
locale?: string;
|
|
27
|
+
};
|
|
28
|
+
type SetBlogFeedbackInput = {
|
|
29
|
+
visitorKey: string;
|
|
30
|
+
action: 'set' | 'clear';
|
|
31
|
+
comment?: string;
|
|
32
|
+
locale?: string;
|
|
33
|
+
};
|
|
34
|
+
/** Raw article payload from BFF / Mailoo blog API */
|
|
35
|
+
interface BlogPostApiData {
|
|
36
|
+
id: string;
|
|
37
|
+
title: string;
|
|
38
|
+
slug: string;
|
|
39
|
+
excerpt?: string | null;
|
|
40
|
+
content: string;
|
|
41
|
+
htmlContent?: string | null;
|
|
42
|
+
publishedAt?: string | null;
|
|
43
|
+
createdAt: string;
|
|
44
|
+
author?: {
|
|
45
|
+
id?: string;
|
|
46
|
+
name?: string | null;
|
|
47
|
+
email?: string | null;
|
|
48
|
+
avatar?: string | null;
|
|
49
|
+
bio?: string | null;
|
|
50
|
+
};
|
|
51
|
+
category?: string | {
|
|
52
|
+
id: string;
|
|
53
|
+
slug: string;
|
|
54
|
+
name: string;
|
|
55
|
+
} | null;
|
|
56
|
+
readTime?: string | null;
|
|
57
|
+
readTimeMinutes?: number | null;
|
|
58
|
+
/** Page visits from external GET slug; not incremented by BFF/MCP reads. */
|
|
59
|
+
accessCount?: number;
|
|
60
|
+
/** Present on slug detail; optional on list. */
|
|
61
|
+
likeCount?: number;
|
|
62
|
+
dislikeCount?: number;
|
|
63
|
+
feedbackCount?: number;
|
|
64
|
+
tags?: BlogTagApi[];
|
|
65
|
+
metaTitle?: string | null;
|
|
66
|
+
metaDescription?: string | null;
|
|
67
|
+
ogImageUrl?: string | null;
|
|
68
|
+
canonicalUrl?: string | null;
|
|
69
|
+
/** Canonical embed prefix (`…/images/public/content?id=`). Not anonymously fetchable. */
|
|
70
|
+
imagePublicEmbedBaseUrl?: string;
|
|
71
|
+
seoWords?: Array<{
|
|
72
|
+
slug: string;
|
|
73
|
+
word: string;
|
|
74
|
+
}>;
|
|
75
|
+
linkedLinks?: BlogPostLinkedLinkApi[];
|
|
76
|
+
}
|
|
77
|
+
interface BlogCategoryApi {
|
|
78
|
+
id: string;
|
|
79
|
+
slug: string;
|
|
80
|
+
name: string;
|
|
81
|
+
}
|
|
82
|
+
interface BlogTagApi {
|
|
83
|
+
slug: string;
|
|
84
|
+
name: string;
|
|
85
|
+
}
|
|
86
|
+
interface BlogListQuery {
|
|
87
|
+
locale?: string;
|
|
88
|
+
limit?: number;
|
|
89
|
+
page?: number;
|
|
90
|
+
categoryId?: string;
|
|
91
|
+
category?: string;
|
|
92
|
+
intentId?: string;
|
|
93
|
+
audienceId?: string;
|
|
94
|
+
seoClusterId?: string;
|
|
95
|
+
tag?: string;
|
|
96
|
+
[key: string]: string | number | undefined;
|
|
97
|
+
}
|
|
98
|
+
/** Pagination sibling on the external blog list envelope. */
|
|
99
|
+
type BlogListPagination = {
|
|
100
|
+
page: number;
|
|
101
|
+
limit: number;
|
|
102
|
+
total: number;
|
|
103
|
+
totalPages: number;
|
|
104
|
+
hasNextPage: boolean;
|
|
105
|
+
hasPrevPage: boolean;
|
|
106
|
+
};
|
|
107
|
+
/** ISR / cache hint for direct Mailoo API fetches (Next.js `fetch`). */
|
|
108
|
+
type MailooBlogFetchOptions = {
|
|
109
|
+
/** Seconds; default 60. Pass 0 to skip ISR. */
|
|
110
|
+
revalidate?: number;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
declare function firstEmbedImageUrlFromArticle(htmlContent: string | null | undefined, markdownContent: string | null | undefined): string | null;
|
|
114
|
+
/**
|
|
115
|
+
* Default Tailwind Typography class string for article body.
|
|
116
|
+
* Hosts may pass a custom `className` instead.
|
|
117
|
+
*/
|
|
118
|
+
declare const BLOG_ARTICLE_PROSE_CLASSNAME: string;
|
|
119
|
+
|
|
120
|
+
export { type BlogPostApiData as B, type MailooBlogFetchOptions as M, type SetBlogReactionInput as S, type BlogPostLinkedLinkApi as a, type BlogCategoryApi as b, type BlogTagApi as c, type BlogListQuery as d, type BlogListPagination as e, type BlogPostReactionSentiment as f, type BlogArticleMarkCounts as g, type BlogArticleMarkState as h, type SetBlogFeedbackInput as i, BLOG_ARTICLE_PROSE_CLASSNAME as j, firstEmbedImageUrlFromArticle as k };
|
package/package.json
CHANGED
|
@@ -1,6 +1,113 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mailoo/blog",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.33.0",
|
|
4
|
+
"description": "Headless Mailoo Blog module for Next.js (BFF routes, server client, components)",
|
|
5
|
+
"license": "LicenseRef-Mailoo-NoModification",
|
|
6
|
+
"homepage": "https://mailoo.app/en/support/docs/integrations/nextjs-packages",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"mailoo",
|
|
9
|
+
"nextjs",
|
|
10
|
+
"blog"
|
|
11
|
+
],
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
17
|
+
"module": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"require": "./dist/index.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./server": {
|
|
26
|
+
"types": "./dist/server/index.d.ts",
|
|
27
|
+
"import": "./dist/server/index.js",
|
|
28
|
+
"require": "./dist/server/index.cjs"
|
|
29
|
+
},
|
|
30
|
+
"./routes": {
|
|
31
|
+
"types": "./dist/routes/index.d.ts",
|
|
32
|
+
"import": "./dist/routes/index.js",
|
|
33
|
+
"require": "./dist/routes/index.cjs"
|
|
34
|
+
},
|
|
35
|
+
"./client": {
|
|
36
|
+
"types": "./dist/client/index.d.ts",
|
|
37
|
+
"import": "./dist/client/index.js",
|
|
38
|
+
"require": "./dist/client/index.cjs"
|
|
39
|
+
},
|
|
40
|
+
"./client/article-body": {
|
|
41
|
+
"types": "./dist/client/article-body.d.ts",
|
|
42
|
+
"import": "./dist/client/article-body.js",
|
|
43
|
+
"require": "./dist/client/article-body.cjs"
|
|
44
|
+
},
|
|
45
|
+
"./client/linked-links": {
|
|
46
|
+
"types": "./dist/client/linked-links.d.ts",
|
|
47
|
+
"import": "./dist/client/linked-links.js",
|
|
48
|
+
"require": "./dist/client/linked-links.cjs"
|
|
49
|
+
},
|
|
50
|
+
"./client/printable": {
|
|
51
|
+
"types": "./dist/client/printable.d.ts",
|
|
52
|
+
"import": "./dist/client/printable.js",
|
|
53
|
+
"require": "./dist/client/printable.cjs"
|
|
54
|
+
},
|
|
55
|
+
"./client/marks": {
|
|
56
|
+
"types": "./dist/client/marks.d.ts",
|
|
57
|
+
"import": "./dist/client/marks.js",
|
|
58
|
+
"require": "./dist/client/marks.cjs"
|
|
59
|
+
},
|
|
60
|
+
"./client/share": {
|
|
61
|
+
"types": "./dist/client/share.d.ts",
|
|
62
|
+
"import": "./dist/client/share.js",
|
|
63
|
+
"require": "./dist/client/share.cjs"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"files": [
|
|
67
|
+
"dist",
|
|
68
|
+
"README.md",
|
|
69
|
+
"LICENSE"
|
|
70
|
+
],
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"@mailoo/images": "1.33.0"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"@mailoo/next-core": "^1.18.4",
|
|
76
|
+
"next": ">=16.3.4",
|
|
77
|
+
"react": ">=18.3.1",
|
|
78
|
+
"react-dom": ">=18.3.1",
|
|
79
|
+
"react-markdown": ">=9.1.0",
|
|
80
|
+
"remark-gfm": ">=4.0.1"
|
|
81
|
+
},
|
|
82
|
+
"peerDependenciesMeta": {
|
|
83
|
+
"react-markdown": {
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"remark-gfm": {
|
|
87
|
+
"optional": true
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"devDependencies": {
|
|
91
|
+
"@mailoo/next-core": "1.33.0",
|
|
92
|
+
"@types/node": "^25.9.5",
|
|
93
|
+
"@types/react": "^19.2.18",
|
|
94
|
+
"next": "^16.3.4",
|
|
95
|
+
"react": "^19.2.8",
|
|
96
|
+
"react-dom": "^19.2.8",
|
|
97
|
+
"react-markdown": "^10.1.0",
|
|
98
|
+
"remark-gfm": "^4.0.1",
|
|
99
|
+
"tsup": "^8.5.1",
|
|
100
|
+
"typescript": "^5.9.3",
|
|
101
|
+
"vitest": "^4.1.10"
|
|
102
|
+
},
|
|
103
|
+
"engines": {
|
|
104
|
+
"node": ">=20.20.2"
|
|
105
|
+
},
|
|
106
|
+
"scripts": {
|
|
107
|
+
"build": "tsup",
|
|
108
|
+
"clean": "rm -rf dist .turbo",
|
|
109
|
+
"dev": "tsup --watch",
|
|
110
|
+
"test": "vitest run",
|
|
111
|
+
"type-check": "tsc --noEmit"
|
|
112
|
+
}
|
|
6
113
|
}
|