@autoblogwriter/sdk 3.0.1 → 3.0.3
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 +2 -2
- package/dist/index.cjs +6 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/{metadata-D1acl8ZW.d.cts → metadata-CE4bus6R.d.cts} +1 -1
- package/dist/{metadata-CeyU-t7o.d.ts → metadata-DprVkArj.d.ts} +1 -1
- package/dist/next.cjs +7 -1
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +3 -2
- package/dist/next.d.ts +3 -2
- package/dist/next.js +7 -1
- package/dist/next.js.map +1 -1
- package/dist/react.cjs +2 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +2 -0
- package/dist/react.js.map +1 -1
- package/dist/revalidate.d.cts +1 -1
- package/dist/revalidate.d.ts +1 -1
- package/dist/styles.css +34 -0
- package/dist/{types-ClZVNiGd.d.cts → types-HIhu-PBU.d.cts} +2 -0
- package/dist/{types-ClZVNiGd.d.ts → types-HIhu-PBU.d.ts} +2 -0
- package/package.json +1 -1
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render.ts","../src/react/Markdown.tsx","../src/react/BlogPost.tsx","../src/react/BlogPostList.tsx"],"sourcesContent":["const CODE_BLOCK_TOKEN = \"__AUTOBLOGWRITER_CODE_BLOCK_\";\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction renderInline(input: string): string {\n let output = escapeHtml(input);\n output = output.replace(/\\*\\*(.+?)\\*\\*/g, \"<strong>$1</strong>\");\n output = output.replace(/\\*(.+?)\\*/g, \"<em>$1</em>\");\n output = output.replace(/`([^`]+)`/g, (_, code) => `<code>${code}</code>`);\n output = output.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (_, alt, src) => {\n const safeSrc = escapeHtml(src);\n const safeAlt = escapeHtml(alt);\n return `<img src=\"${safeSrc}\" alt=\"${safeAlt}\" />`;\n });\n output = output.replace(/\\[(.+?)\\]\\((.+?)\\)/g, (_, label, href) => {\n const safeHref = escapeHtml(href);\n return `<a href=\"${safeHref}\" target=\"_blank\" rel=\"noreferrer\">${label}</a>`;\n });\n output = output.replace(/\\n/g, \"<br />\");\n return output;\n}\n\nfunction replaceCodeBlocks(markdown: string, blocks: string[]): string {\n return markdown.replace(/```([\\s\\S]*?)```/g, (_, code) => {\n const index = blocks.push(`<pre><code>${escapeHtml(code.trim())}</code></pre>`) - 1;\n return `${CODE_BLOCK_TOKEN}${index}__`;\n });\n}\n\nfunction restoreCodeBlocks(html: string, blocks: string[]): string {\n return html.replace(/__AUTOBLOGWRITER_CODE_BLOCK_(\\d+)__/g, (_, rawIndex) => blocks[Number(rawIndex)] ?? \"\");\n}\n\nexport function renderMarkdownToHtml(markdown: string): string {\n if (!markdown) {\n return \"\";\n }\n\n const codeBlocks: string[] = [];\n const withoutCode = replaceCodeBlocks(markdown, codeBlocks);\n const normalized = withoutCode.replace(/\\r\\n/g, \"\\n\");\n // Insert blank lines around heading lines so they become separate blocks\n const withHeadingBreaks = normalized\n .replace(/\\n(#{1,6}\\s)/g, \"\\n\\n$1\")\n .replace(/(#{1,6}\\s[^\\n]+)\\n(?!#|\\n)/g, \"$1\\n\\n\");\n const blocks = withHeadingBreaks\n .split(/\\n{2,}/)\n .map((block) => block.trim())\n .filter(Boolean);\n\n const htmlBlocks = blocks.map((block) => {\n const headingMatch = block.match(/^(#{1,6})\\s+(.*)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n const content = renderInline(headingMatch[2]);\n return `<h${level}>${content}</h${level}>`;\n }\n\n // Check if block is a standalone image\n const imageMatch = block.match(/^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/);\n if (imageMatch) {\n const safeSrc = escapeHtml(imageMatch[2]);\n const safeAlt = escapeHtml(imageMatch[1]);\n return `<img src=\"${safeSrc}\" alt=\"${safeAlt}\" />`;\n }\n\n return `<p>${renderInline(block)}</p>`;\n });\n\n const html = htmlBlocks.join(\"\\n\");\n return restoreCodeBlocks(html, codeBlocks);\n}\n","import { renderMarkdownToHtml } from \"../render\";\n\nexport interface MarkdownProps {\n source?: string | null;\n className?: string;\n}\n\nexport function Markdown({ source, className = \"ba-markdown\" }: MarkdownProps) {\n if (!source) {\n return null;\n }\n\n return (\n <div\n className={className}\n dangerouslySetInnerHTML={{ __html: renderMarkdownToHtml(source) }}\n />\n );\n}\n","import type { BlogPost as BlogPostType } from \"../types\";\nimport { Markdown } from \"./Markdown\";\n\nexport interface BlogPostProps {\n post: BlogPostType;\n showTitle?: boolean;\n showDate?: boolean;\n className?: string;\n renderContent?: (content: string) => React.ReactNode;\n}\n\nfunction formatDate(dateStr: string): string {\n return new Date(dateStr).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n}\n\nexport function BlogPost({\n post,\n showTitle = true,\n showDate = true,\n className = \"ba-post\",\n renderContent,\n}: BlogPostProps) {\n const readingTime = post.metadata?.readingTimeMinutes;\n const dateStr = post.publishedAt ?? post.updatedAt;\n\n return (\n <article className={className}>\n {showTitle && <h1 className=\"ba-post-title\">{post.title}</h1>}\n {(showDate || readingTime) && (\n <p className=\"ba-post-meta\">\n {showDate && (\n <time dateTime={dateStr}>{formatDate(dateStr)}</time>\n )}\n {showDate && readingTime && <span className=\"ba-post-meta-sep\"> · </span>}\n {readingTime && (\n <span className=\"ba-post-reading-time\">{readingTime} min read</span>\n )}\n </p>\n )}\n {renderContent ? renderContent(post.content) : <Markdown source={post.content} />}\n </article>\n );\n}\n","import type { BlogPost } from \"../types\";\nimport { Markdown } from \"./Markdown\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype LinkComponent = React.ComponentType<any>;\n\nexport interface BlogPostListProps {\n posts: BlogPost[];\n title?: string;\n routePrefix?: string;\n linkComponent?: LinkComponent;\n className?: string;\n renderCard?: (post: BlogPost, href: string) => React.ReactNode;\n}\n\nfunction DefaultLink({\n href,\n className,\n children,\n}: {\n href: string;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <a href={href} className={className}>\n {children}\n </a>\n );\n}\n\nfunction formatDate(dateStr: string): string {\n return new Date(dateStr).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n}\n\nexport function BlogPostList({\n posts,\n title = \"Latest posts\",\n routePrefix = \"/blog\",\n linkComponent,\n className = \"ba-listing\",\n renderCard,\n}: BlogPostListProps) {\n const Link = linkComponent ?? DefaultLink;\n const prefix = routePrefix.replace(/\\/$/, \"\");\n\n return (\n <section className={className}>\n {title && <h1 className=\"ba-listing-title\">{title}</h1>}\n <div className=\"ba-posts\">\n {posts.map((post) => {\n const href = `${prefix}/${post.slug}`;\n\n if (renderCard) {\n return <div key={post.id}>{renderCard(post, href)}</div>;\n }\n\n const dateStr = post.publishedAt ?? post.updatedAt;\n\n return (\n <article key={post.id} className=\"ba-post-card\">\n <h2 className=\"ba-post-card-title\">\n <Link href={href} className=\"ba-post-card-link\">\n {post.title}\n </Link>\n </h2>\n <p className=\"ba-post-card-meta\">\n <time dateTime={dateStr}>{formatDate(dateStr)}</time>\n </p>\n <div className=\"ba-post-card-excerpt\">\n <Markdown source={post.excerpt ?? post.content.slice(0, 180)} />\n </div>\n </article>\n );\n })}\n </div>\n </section>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsxs","formatDate"]}
|
|
1
|
+
{"version":3,"sources":["../src/render.ts","../src/react/Markdown.tsx","../src/react/BlogPost.tsx","../src/react/BlogPostList.tsx"],"sourcesContent":["const CODE_BLOCK_TOKEN = \"__AUTOBLOGWRITER_CODE_BLOCK_\";\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction renderInline(input: string): string {\n let output = escapeHtml(input);\n output = output.replace(/\\*\\*(.+?)\\*\\*/g, \"<strong>$1</strong>\");\n output = output.replace(/\\*(.+?)\\*/g, \"<em>$1</em>\");\n output = output.replace(/`([^`]+)`/g, (_, code) => `<code>${code}</code>`);\n output = output.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, (_, alt, src) => {\n const safeSrc = escapeHtml(src);\n const safeAlt = escapeHtml(alt);\n return `<img src=\"${safeSrc}\" alt=\"${safeAlt}\" />`;\n });\n output = output.replace(/\\[(.+?)\\]\\((.+?)\\)/g, (_, label, href) => {\n const safeHref = escapeHtml(href);\n return `<a href=\"${safeHref}\" target=\"_blank\" rel=\"noreferrer\">${label}</a>`;\n });\n output = output.replace(/\\n/g, \"<br />\");\n return output;\n}\n\nfunction replaceCodeBlocks(markdown: string, blocks: string[]): string {\n return markdown.replace(/```([\\s\\S]*?)```/g, (_, code) => {\n const index = blocks.push(`<pre><code>${escapeHtml(code.trim())}</code></pre>`) - 1;\n return `${CODE_BLOCK_TOKEN}${index}__`;\n });\n}\n\nfunction restoreCodeBlocks(html: string, blocks: string[]): string {\n return html.replace(/__AUTOBLOGWRITER_CODE_BLOCK_(\\d+)__/g, (_, rawIndex) => blocks[Number(rawIndex)] ?? \"\");\n}\n\nexport function renderMarkdownToHtml(markdown: string): string {\n if (!markdown) {\n return \"\";\n }\n\n const codeBlocks: string[] = [];\n const withoutCode = replaceCodeBlocks(markdown, codeBlocks);\n const normalized = withoutCode.replace(/\\r\\n/g, \"\\n\");\n // Insert blank lines around heading lines so they become separate blocks\n const withHeadingBreaks = normalized\n .replace(/\\n(#{1,6}\\s)/g, \"\\n\\n$1\")\n .replace(/(#{1,6}\\s[^\\n]+)\\n(?!#|\\n)/g, \"$1\\n\\n\");\n const blocks = withHeadingBreaks\n .split(/\\n{2,}/)\n .map((block) => block.trim())\n .filter(Boolean);\n\n const htmlBlocks = blocks.map((block) => {\n const headingMatch = block.match(/^(#{1,6})\\s+(.*)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n const content = renderInline(headingMatch[2]);\n return `<h${level}>${content}</h${level}>`;\n }\n\n // Check if block is a standalone image\n const imageMatch = block.match(/^!\\[([^\\]]*)\\]\\(([^)]+)\\)$/);\n if (imageMatch) {\n const safeSrc = escapeHtml(imageMatch[2]);\n const safeAlt = escapeHtml(imageMatch[1]);\n return `<img src=\"${safeSrc}\" alt=\"${safeAlt}\" />`;\n }\n\n return `<p>${renderInline(block)}</p>`;\n });\n\n const html = htmlBlocks.join(\"\\n\");\n return restoreCodeBlocks(html, codeBlocks);\n}\n","import { renderMarkdownToHtml } from \"../render\";\n\nexport interface MarkdownProps {\n source?: string | null;\n className?: string;\n}\n\nexport function Markdown({ source, className = \"ba-markdown\" }: MarkdownProps) {\n if (!source) {\n return null;\n }\n\n return (\n <div\n className={className}\n dangerouslySetInnerHTML={{ __html: renderMarkdownToHtml(source) }}\n />\n );\n}\n","import type { BlogPost as BlogPostType } from \"../types\";\nimport { Markdown } from \"./Markdown\";\n\nexport interface BlogPostProps {\n post: BlogPostType;\n showTitle?: boolean;\n showDate?: boolean;\n className?: string;\n renderContent?: (content: string) => React.ReactNode;\n}\n\nfunction formatDate(dateStr: string): string {\n return new Date(dateStr).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n}\n\nexport function BlogPost({\n post,\n showTitle = true,\n showDate = true,\n className = \"ba-post\",\n renderContent,\n}: BlogPostProps) {\n const readingTime = post.metadata?.readingTimeMinutes;\n const dateStr = post.publishedAt ?? post.updatedAt;\n\n return (\n <article className={className}>\n {showTitle && <h1 className=\"ba-post-title\">{post.title}</h1>}\n {post.categories && post.categories.length > 0 && (\n <div className=\"ba-post-categories\" aria-label=\"Categories\">\n {post.categories.map((category) => (\n <span key={category} className=\"ba-category-chip\">\n {category}\n </span>\n ))}\n </div>\n )}\n {(showDate || readingTime) && (\n <p className=\"ba-post-meta\">\n {showDate && (\n <time dateTime={dateStr}>{formatDate(dateStr)}</time>\n )}\n {showDate && readingTime && <span className=\"ba-post-meta-sep\"> · </span>}\n {readingTime && (\n <span className=\"ba-post-reading-time\">{readingTime} min read</span>\n )}\n </p>\n )}\n {renderContent ? renderContent(post.content) : <Markdown source={post.content} />}\n </article>\n );\n}\n","import type { BlogPost } from \"../types\";\nimport { Markdown } from \"./Markdown\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype LinkComponent = React.ComponentType<any>;\n\nexport interface BlogPostListProps {\n posts: BlogPost[];\n title?: string;\n routePrefix?: string;\n linkComponent?: LinkComponent;\n className?: string;\n renderCard?: (post: BlogPost, href: string) => React.ReactNode;\n}\n\nfunction DefaultLink({\n href,\n className,\n children,\n}: {\n href: string;\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <a href={href} className={className}>\n {children}\n </a>\n );\n}\n\nfunction formatDate(dateStr: string): string {\n return new Date(dateStr).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n}\n\nexport function BlogPostList({\n posts,\n title = \"Latest posts\",\n routePrefix = \"/blog\",\n linkComponent,\n className = \"ba-listing\",\n renderCard,\n}: BlogPostListProps) {\n const Link = linkComponent ?? DefaultLink;\n const prefix = routePrefix.replace(/\\/$/, \"\");\n\n return (\n <section className={className}>\n {title && <h1 className=\"ba-listing-title\">{title}</h1>}\n <div className=\"ba-posts\">\n {posts.map((post) => {\n const href = `${prefix}/${post.slug}`;\n\n if (renderCard) {\n return <div key={post.id}>{renderCard(post, href)}</div>;\n }\n\n const dateStr = post.publishedAt ?? post.updatedAt;\n\n return (\n <article key={post.id} className=\"ba-post-card\">\n {post.categories && post.categories.length > 0 && (\n <div className=\"ba-post-card-categories\" aria-label=\"Categories\">\n {post.categories.map((category) => (\n <span key={category} className=\"ba-category-chip\">\n {category}\n </span>\n ))}\n </div>\n )}\n <h2 className=\"ba-post-card-title\">\n <Link href={href} className=\"ba-post-card-link\">\n {post.title}\n </Link>\n </h2>\n <p className=\"ba-post-card-meta\">\n <time dateTime={dateStr}>{formatDate(dateStr)}</time>\n </p>\n <div className=\"ba-post-card-excerpt\">\n <Markdown source={post.excerpt ?? post.content.slice(0, 180)} />\n </div>\n </article>\n );\n })}\n </div>\n </section>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsxs","formatDate"]}
|
package/dist/revalidate.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as RevalidatePathFn, g as RevalidateTagFn, f as AutoBlogWriterRevalidatePayload } from './types-
|
|
1
|
+
import { R as RevalidatePathFn, g as RevalidateTagFn, f as AutoBlogWriterRevalidatePayload } from './types-HIhu-PBU.cjs';
|
|
2
2
|
|
|
3
3
|
interface VerifyWebhookSignatureOptions {
|
|
4
4
|
rawBody: string | Buffer;
|
package/dist/revalidate.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R as RevalidatePathFn, g as RevalidateTagFn, f as AutoBlogWriterRevalidatePayload } from './types-
|
|
1
|
+
import { R as RevalidatePathFn, g as RevalidateTagFn, f as AutoBlogWriterRevalidatePayload } from './types-HIhu-PBU.js';
|
|
2
2
|
|
|
3
3
|
interface VerifyWebhookSignatureOptions {
|
|
4
4
|
rawBody: string | Buffer;
|
package/dist/styles.css
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
--ba-color-border-hover: rgba(255, 255, 255, 0.12);
|
|
13
13
|
--ba-color-card-bg: rgba(255, 255, 255, 0.02);
|
|
14
14
|
--ba-color-card-bg-hover: rgba(255, 255, 255, 0.04);
|
|
15
|
+
--ba-color-chip-bg: linear-gradient(120deg, rgba(0, 212, 255, 0.14), rgba(127, 255, 212, 0.12));
|
|
16
|
+
--ba-color-chip-border: rgba(108, 204, 255, 0.35);
|
|
17
|
+
--ba-color-chip-text: #d9f6ff;
|
|
15
18
|
--ba-color-code-bg: rgba(255, 255, 255, 0.1);
|
|
16
19
|
--ba-color-pre-bg: rgba(255, 255, 255, 0.05);
|
|
17
20
|
--ba-color-img-shadow: rgba(0, 0, 0, 0.3);
|
|
@@ -58,6 +61,13 @@
|
|
|
58
61
|
transform: translateY(-2px);
|
|
59
62
|
}
|
|
60
63
|
|
|
64
|
+
.ba-post-card-categories {
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-wrap: wrap;
|
|
67
|
+
gap: 0.5rem;
|
|
68
|
+
margin-bottom: 0.85rem;
|
|
69
|
+
}
|
|
70
|
+
|
|
61
71
|
.ba-post-card-title {
|
|
62
72
|
margin: 0 0 0.5rem 0;
|
|
63
73
|
font-size: 1.5rem;
|
|
@@ -113,6 +123,30 @@
|
|
|
113
123
|
letter-spacing: -0.02em;
|
|
114
124
|
}
|
|
115
125
|
|
|
126
|
+
.ba-post-categories {
|
|
127
|
+
display: flex;
|
|
128
|
+
flex-wrap: wrap;
|
|
129
|
+
gap: 0.55rem;
|
|
130
|
+
margin: 0 0 1rem 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.ba-category-chip {
|
|
134
|
+
display: inline-flex;
|
|
135
|
+
align-items: center;
|
|
136
|
+
justify-content: center;
|
|
137
|
+
border: 1px solid var(--ba-color-chip-border);
|
|
138
|
+
background: var(--ba-color-chip-bg);
|
|
139
|
+
color: var(--ba-color-chip-text);
|
|
140
|
+
border-radius: 999px;
|
|
141
|
+
padding: 0.24rem 0.66rem;
|
|
142
|
+
font-size: 0.73rem;
|
|
143
|
+
letter-spacing: 0.06em;
|
|
144
|
+
text-transform: uppercase;
|
|
145
|
+
font-weight: 600;
|
|
146
|
+
line-height: 1.3;
|
|
147
|
+
backdrop-filter: blur(4px);
|
|
148
|
+
}
|
|
149
|
+
|
|
116
150
|
.ba-post-meta {
|
|
117
151
|
margin: 0 0 2rem 0;
|
|
118
152
|
font-size: 0.875rem;
|
|
@@ -22,6 +22,7 @@ interface BlogPost {
|
|
|
22
22
|
title: string;
|
|
23
23
|
slug: string;
|
|
24
24
|
excerpt?: string;
|
|
25
|
+
categories?: string[];
|
|
25
26
|
content: string;
|
|
26
27
|
status: "DRAFT" | "PUBLISHED" | "HIDDEN";
|
|
27
28
|
seo?: {
|
|
@@ -31,6 +32,7 @@ interface BlogPost {
|
|
|
31
32
|
};
|
|
32
33
|
metadata?: {
|
|
33
34
|
canonicalUrl?: string;
|
|
35
|
+
heroImageUrl?: string;
|
|
34
36
|
ogImageUrl?: string;
|
|
35
37
|
readingTimeMinutes?: number;
|
|
36
38
|
wordCount?: number;
|
|
@@ -22,6 +22,7 @@ interface BlogPost {
|
|
|
22
22
|
title: string;
|
|
23
23
|
slug: string;
|
|
24
24
|
excerpt?: string;
|
|
25
|
+
categories?: string[];
|
|
25
26
|
content: string;
|
|
26
27
|
status: "DRAFT" | "PUBLISHED" | "HIDDEN";
|
|
27
28
|
seo?: {
|
|
@@ -31,6 +32,7 @@ interface BlogPost {
|
|
|
31
32
|
};
|
|
32
33
|
metadata?: {
|
|
33
34
|
canonicalUrl?: string;
|
|
35
|
+
heroImageUrl?: string;
|
|
34
36
|
ogImageUrl?: string;
|
|
35
37
|
readingTimeMinutes?: number;
|
|
36
38
|
wordCount?: number;
|
package/package.json
CHANGED