@autoblogwriter/sdk 2.0.0 → 2.0.2

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 CHANGED
@@ -1,6 +1,8 @@
1
1
  # @autoblogwriter/sdk
2
2
 
3
- Official TypeScript SDK for BlogAuto. It keeps server-side integration tiny, adds helpers for Next.js App Router and Vite/React apps, and ships revalidation utilities that respect BlogAuto's API contract.
3
+ Official TypeScript SDK for AutoBlogWriter. It keeps server-side integration tiny, adds helpers for Next.js App Router and Vite/React apps, and ships revalidation utilities that respect AutoBlogWriter's API contract.
4
+
5
+ **[Documentation](https://docs.autoblogwriter.app/)**
4
6
 
5
7
  ## Installation
6
8
 
@@ -11,7 +13,7 @@ npm install @autoblogwriter/sdk
11
13
  > Requires Node.js 18+ and native `fetch`. Bundles ship as ESM, CJS, and types via `tsup`.
12
14
 
13
15
  ## Security Notes (Read First)
14
- - Never ship BlogAuto API keys in public, client-side code.
16
+ - Never ship AutoBlogWriter API keys in public, client-side code.
15
17
  - Run the SDK inside Next.js server components, route handlers, or your own backend proxy.
16
18
  - If you must expose functionality to the browser, issue scoped public tokens or proxy through your server. Do **not** mint new auth schemes.
17
19
 
@@ -21,7 +23,7 @@ npm install @autoblogwriter/sdk
21
23
  import { createBlogAutoClient } from "@autoblogwriter/sdk";
22
24
 
23
25
  const client = createBlogAutoClient({
24
- apiUrl: "https://api.blogauto.io",
26
+ apiUrl: "https://api.autoblogwriter.app",
25
27
  apiKey: process.env.BLOGAUTO_API_KEY!,
26
28
  workspaceId: process.env.BLOGAUTO_WORKSPACE_ID,
27
29
  workspaceSlug: process.env.BLOGAUTO_WORKSPACE_SLUG,
@@ -34,8 +36,8 @@ const client = createBlogAutoClient({
34
36
 
35
37
  | Option | Type | Required | Description |
36
38
  | --- | --- | --- | --- |
37
- | `apiUrl` | `string` | yes | Root API URL, e.g. `https://api.blogauto.io`. Trailing slash removed automatically. |
38
- | `apiKey` | `string` | yes | Workspace-scoped API key created in the BlogAuto dashboard. |
39
+ | `apiUrl` | `string` | yes | Root API URL, e.g. `https://api.autoblogwriter.app`. Trailing slash removed automatically. |
40
+ | `apiKey` | `string` | yes | Workspace-scoped API key created in the AutoBlogWriter dashboard. |
39
41
  | `workspaceId` | `string` | one of `workspaceId` or `workspaceSlug` | Optional; used for account scoping. |
40
42
  | `workspaceSlug` | `string` | one of `workspaceId` or `workspaceSlug` | Required for public content APIs (`/v1/public/:workspaceSlug/...`). |
41
43
  | `authMode` | `"bearer" \| "x-api-key"` | no (default `"bearer"`) | Sends the API key via `Authorization: Bearer` or `x-api-key`. |
@@ -210,10 +212,10 @@ export function BlogList() {
210
212
 
211
213
  ## Automatic Revalidation Setup
212
214
 
213
- When BlogAuto publishes a post it can ping your Next.js App Router site so sitemap, robots, and cached blog pages refresh immediately.
215
+ When AutoBlogWriter publishes a post it can ping your Next.js App Router site so sitemap, robots, and cached blog pages refresh immediately.
214
216
 
215
217
  1. **Configure your workspace**
216
- - In the BlogAuto dashboard open **Workspace Settings → Revalidation URL** and set your endpoint (e.g., `https://yoursite.com/api/blogauto/revalidate`).
218
+ - In the AutoBlogWriter dashboard open **Workspace Settings → Revalidation URL** and set your endpoint (e.g., `https://yoursite.com/api/blogauto/revalidate`).
217
219
  - Generate a **Revalidation Webhook secret**, copy the plain secret once, and store it as `BLOGAUTO_REVALIDATE_SECRET`.
218
220
  2. **Create the route handler**
219
221
 
@@ -238,7 +240,7 @@ export const POST = createRevalidateRouteHandler({
238
240
  });
239
241
  ```
240
242
 
241
- The handler verifies the `X-BlogAuto-Signature` HMAC header, enforces timestamp skew (default 5minutes), and revalidates:
243
+ The handler verifies the `X-BlogAuto-Signature` HMAC header, enforces timestamp skew (default 5 minutes), and revalidates:
242
244
 
243
245
  - Paths: `/sitemap.xml`, `/robots.txt`, `/blog`, `/blog/:slug`
244
246
  - Tags: `blogauto:<workspaceSlug>:sitemap`, `blogauto:<workspaceSlug>:posts`, and `blogauto:<workspaceSlug>:post:<slug>`
package/dist/index.cjs CHANGED
@@ -639,8 +639,6 @@ function createBlogAutoFromEnv() {
639
639
  const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;
640
640
  const siteUrl = process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000";
641
641
  const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;
642
- const analyticsToken = process.env.NEXT_PUBLIC_ANALYTICS_TOKEN;
643
- const analyticsProxy = process.env.NEXT_PUBLIC_ANALYTICS_PROXY ?? "/api/blogauto/analytics";
644
642
  const client = createBlogAutoClient({
645
643
  apiUrl,
646
644
  apiKey,
@@ -653,8 +651,6 @@ function createBlogAutoFromEnv() {
653
651
  workspaceId,
654
652
  siteUrl,
655
653
  revalidateSecret,
656
- analyticsToken,
657
- analyticsProxy,
658
654
  apiUrl,
659
655
  apiKey,
660
656
  tags: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/auth.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/sitemap.ts","../src/robots.ts","../src/render.ts","../src/revalidate.ts","../src/metadata.ts","../src/env.ts"],"sourcesContent":["export { createBlogAutoClient } from \"./client\";\nexport type { BlogAutoClient } from \"./client\";\n\nexport { buildSitemap } from \"./sitemap\";\nexport { buildRobots } from \"./robots\";\nexport { renderMarkdownToHtml } from \"./render\";\nexport { verifyWebhookSignature, createRevalidateRouteHandler } from \"./revalidate\";\nexport { buildNextMetadata, type NextMetadata } from \"./metadata\";\n\nexport { buildAuthHeaders } from \"./auth\";\nexport { DEFAULT_TIMEOUT_MS, resolveClientConfig } from \"./utils\";\nexport { BlogAutoError, ConfigError, ApiError, NotFoundError } from \"./errors\";\nexport { createBlogAutoFromEnv, type BlogAutoEnvConfig } from \"./env\";\n\nexport type {\n BlogAutoClientConfig,\n BlogPost,\n BuildRobotsOptions,\n BuildSitemapOptions,\n MetadataRouteRobots,\n MetadataRouteSitemap,\n PaginatedList,\n PostsResponse,\n SitemapEntry,\n BlogAutoRevalidatePayload,\n RevalidatePathFn,\n RevalidateTagFn,\n FetchRequestOptions,\n FetchNextConfig,\n} from \"./types\";\n","import { AuthMode } from \"./types\";\n\nexport function buildAuthHeaders(apiKey: string, authMode: AuthMode = \"bearer\"): Record<string, string> {\n if (authMode === \"x-api-key\") {\n return { \"x-api-key\": apiKey };\n }\n return { Authorization: `Bearer ${apiKey}` };\n}\n","export class BlogAutoError extends Error {\n public readonly causeError?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = new.target.name;\n this.causeError = options?.cause;\n }\n}\n\nexport class ConfigError extends BlogAutoError {}\n\nexport interface ApiErrorDetails {\n status: number;\n code?: string;\n details?: unknown;\n}\n\nexport class ApiError extends BlogAutoError {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, info: ApiErrorDetails, options?: { cause?: unknown }) {\n super(message, options);\n this.status = info.status;\n this.code = info.code;\n this.details = info.details;\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, info?: Partial<ApiErrorDetails>) {\n super(message, { status: info?.status ?? 404, code: info?.code, details: info?.details });\n }\n}\n","import { ApiError, ConfigError } from \"./errors\";\nimport { AuthMode, BlogAutoClientConfig, InternalClientConfig } from \"./types\";\n\nexport const DEFAULT_TIMEOUT_MS = 10_000;\n\nexport function normalizeApiUrl(apiUrl: string): string {\n if (!apiUrl) {\n throw new ConfigError(\"apiUrl is required\");\n }\n\n return apiUrl.replace(/\\/$/, \"\");\n}\n\nexport function resolveClientConfig(config: BlogAutoClientConfig): InternalClientConfig {\n if (!config) {\n throw new ConfigError(\"Client configuration is required\");\n }\n\n const apiKey = config.apiKey?.trim();\n if (!apiKey) {\n throw new ConfigError(\"apiKey is required to authenticate with BlogAuto\");\n }\n\n if (!config.workspaceId && !config.workspaceSlug) {\n throw new ConfigError(\"Provide either workspaceId or workspaceSlug\");\n }\n\n const authMode: AuthMode = config.authMode ?? \"bearer\";\n\n return {\n apiKey,\n apiUrl: normalizeApiUrl(config.apiUrl),\n workspaceId: config.workspaceId,\n workspaceSlug: config.workspaceSlug,\n authMode,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n headers: { ...(config.headers ?? {}) },\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n };\n}\n\nexport function buildQuery(params: Record<string, string | number | undefined | null>): string {\n const query = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n query.set(key, String(value));\n });\n const qs = query.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T> {\n if (!timeoutMs) {\n return promise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new ApiError(`Request timed out after ${timeoutMs}ms`, {\n status: 408,\n }),\n );\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: Array<Record<string, string> | undefined>\n): Record<string, string> {\n return headerObjects.reduce<Record<string, string>>((acc, headers) => {\n if (!headers) {\n return acc;\n }\n Object.entries(headers).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n acc[key.toLowerCase()] = value;\n });\n return acc;\n }, {});\n}\n","import { buildAuthHeaders } from \"./auth\";\nimport { ApiError, BlogAutoError, ConfigError } from \"./errors\";\nimport { buildQuery, mergeHeaders, resolveClientConfig, withTimeout } from \"./utils\";\nimport type {\n BlogAutoClientConfig,\n BlogPost,\n FetchRequestOptions,\n PaginatedList,\n PostsResponse,\n} from \"./types\";\n\ninterface RequestOptions {\n path: string;\n method?: string;\n query?: Record<string, string | number | undefined | null>;\n body?: unknown;\n allowNotFound?: boolean;\n headers?: Record<string, string>;\n cache?: RequestCache;\n next?: FetchRequestOptions[\"next\"];\n}\n\nexport interface BlogAutoClient {\n getPosts(params?: { limit?: number; cursor?: string } & FetchRequestOptions): Promise<PostsResponse>;\n getPostBySlug(slug: string, options?: FetchRequestOptions): Promise<BlogPost | null>;\n getSitemapEntries(): Promise<Array<{ slug: string; updatedAt: string }>>;\n}\n\nexport function createBlogAutoClient(config: BlogAutoClientConfig): BlogAutoClient {\n const resolved = resolveClientConfig(config);\n const fetchImpl = resolved.fetch;\n const debug =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.BLOGAUTO_DEBUG === \"true\";\n const debugLog = (...args: unknown[]) => {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\"[blogauto]\", ...args);\n }\n };\n\n function ensureWorkspaceSlug(): string {\n if (!resolved.workspaceSlug) {\n throw new ConfigError(\"workspaceSlug is required to call the BlogAuto public API\");\n }\n return resolved.workspaceSlug;\n }\n\n function buildUrl(path: string, query?: Record<string, string | number | undefined | null>): string {\n const qs = buildQuery(query ?? {});\n return `${resolved.apiUrl}${path}${qs}`;\n }\n\n function unwrapSuccessPayload<T>(payload: unknown): T {\n if (payload && typeof payload === \"object\") {\n const maybePayload = payload as { success?: boolean; data?: T; error?: { message?: string } };\n if (\"success\" in maybePayload) {\n if (maybePayload.success === false) {\n throw new ApiError(\n maybePayload.error?.message ?? \"BlogAuto request failed\",\n { status: 500, details: maybePayload },\n );\n }\n if (maybePayload.success && \"data\" in maybePayload) {\n return maybePayload.data as T;\n }\n }\n }\n return payload as T;\n }\n\n async function request<T>(opts: RequestOptions): Promise<T> {\n const method = opts.method ?? \"GET\";\n const url = buildUrl(opts.path, opts.query);\n\n const authHeaders = buildAuthHeaders(resolved.apiKey, resolved.authMode);\n const baseHeaders = mergeHeaders(resolved.headers, authHeaders, opts.headers);\n\n const init: RequestInit = {\n method,\n headers: baseHeaders,\n };\n\n if (opts.body) {\n init.body = typeof opts.body === \"string\" ? opts.body : JSON.stringify(opts.body);\n init.headers = {\n ...baseHeaders,\n \"content-type\": baseHeaders[\"content-type\"] ?? \"application/json\",\n };\n }\n\n if (opts.cache !== undefined) {\n init.cache = opts.cache;\n }\n\n if (opts.next) {\n (init as RequestInit & { next?: FetchRequestOptions[\"next\"] }).next = opts.next;\n }\n\n const startedAt = Date.now();\n try {\n const response = await withTimeout(fetchImpl(url, init), resolved.timeoutMs);\n debugLog(\"response\", {\n method,\n url,\n status: response.status,\n durationMs: Date.now() - startedAt,\n });\n if (opts.allowNotFound && response.status === 404) {\n return null as T;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n const payload = isJson ? await response.json().catch(() => undefined) : await response.text();\n\n if (!response.ok) {\n if (response.status === 404 && opts.allowNotFound) {\n return null as T;\n }\n\n const errorBody = payload as any;\n const message =\n errorBody?.error?.message ?? errorBody?.message ?? `Request failed with status ${response.status}`;\n throw new ApiError(message, {\n status: response.status,\n code: errorBody?.error?.code ?? errorBody?.code,\n details: errorBody?.error?.details ?? errorBody,\n });\n }\n\n if (isJson) {\n return unwrapSuccessPayload<T>(payload);\n }\n\n return (payload as T) ?? (undefined as T);\n } catch (error) {\n debugLog(\"request failed\", {\n method,\n url,\n durationMs: Date.now() - startedAt,\n error: error instanceof Error ? error.message : error,\n });\n if (error instanceof BlogAutoError) {\n throw error;\n }\n const causeMessage =\n error instanceof Error ? error.message : typeof error === \"string\" ? error : undefined;\n const message = causeMessage\n ? `Network request to BlogAuto failed: ${causeMessage}`\n : \"Network request to BlogAuto failed\";\n throw new ApiError(\n message,\n {\n status: 0,\n details: { url, method },\n },\n { cause: error },\n );\n }\n }\n\n async function fetchBlogPage(\n limit: number,\n page: number,\n cacheOptions?: FetchRequestOptions,\n ): Promise<PaginatedList<BlogPost>> {\n const workspaceSlug = ensureWorkspaceSlug();\n debugLog(\"fetch posts page\", { workspaceSlug, limit, page });\n return request<PaginatedList<BlogPost>>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs`,\n query: { limit, page },\n cache: cacheOptions?.cache,\n next: cacheOptions?.next,\n });\n }\n\n return {\n async getPosts(params) {\n const limit = params?.limit ?? 20;\n const cursorPage = params?.cursor ? Number(params.cursor) : undefined;\n const page = Number.isFinite(cursorPage) && cursorPage! >= 1 ? cursorPage! : 1;\n const data = await fetchBlogPage(limit, page, params);\n return {\n posts: data.items,\n nextCursor: data.pagination.hasMore ? String(data.pagination.page + 1) : undefined,\n };\n },\n async getPostBySlug(slug: string, options?: FetchRequestOptions) {\n if (!slug) {\n throw new ApiError(\"slug is required\", { status: 400 });\n }\n const workspaceSlug = ensureWorkspaceSlug();\n const post = await request<{ post: BlogPost } | null>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs/${encodeURIComponent(slug)}`,\n allowNotFound: true,\n cache: options?.cache,\n next: options?.next,\n });\n if (post === null) {\n return null;\n }\n return post.post;\n },\n async getSitemapEntries() {\n const entries: Array<{ slug: string; updatedAt: string }> = [];\n const limit = 100;\n let page = 1;\n\n while (true) {\n const pageData = await fetchBlogPage(limit, page);\n pageData.items.forEach((post) => {\n entries.push({ slug: post.slug, updatedAt: post.updatedAt });\n });\n\n if (!pageData.pagination.hasMore) {\n break;\n }\n\n page = pageData.pagination.page + 1;\n }\n\n return entries;\n },\n };\n}\n","import { BuildSitemapOptions, MetadataRouteSitemap, MetadataRouteSitemapEntry } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizeRoutePrefix(routePrefix?: string): string {\n if (!routePrefix || routePrefix === \"/\") {\n return \"\";\n }\n const withSlash = routePrefix.startsWith(\"/\") ? routePrefix : `/${routePrefix}`;\n return withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash;\n}\n\nfunction normalizeSlug(slug: string): string {\n return slug.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function buildSitemap(opts: BuildSitemapOptions): MetadataRouteSitemap {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const prefix = normalizeRoutePrefix(opts.routePrefix ?? \"/blog\");\n\n const entries: MetadataRouteSitemapEntry[] = opts.entries.map((entry) => {\n const slug = normalizeSlug(entry.slug);\n const hasSlug = slug.length > 0;\n const slugFragment = hasSlug ? `/${slug}` : \"\";\n const path = prefix ? `${prefix}${slugFragment}` : hasSlug ? `/${slug}` : \"/\";\n return {\n url: `${siteUrl}${path}`,\n lastModified: entry.updatedAt,\n };\n });\n\n return entries;\n}\n","import { BuildRobotsOptions, MetadataRouteRobots } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n if (!path) {\n return \"/sitemap.xml\";\n }\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n return path;\n}\n\nexport function buildRobots(opts: BuildRobotsOptions): MetadataRouteRobots {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const sitemapPath = normalizePath(opts.sitemapPath ?? \"/sitemap.xml\");\n const sitemapUrl = `${siteUrl}${sitemapPath}`;\n\n return {\n rules: [{ userAgent: \"*\", allow: \"/\" }],\n sitemap: sitemapUrl,\n };\n}\n","const CODE_BLOCK_TOKEN = \"__BLOGAUTO_CODE_BLOCK_\";\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\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(/__BLOGAUTO_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 crypto from \"crypto\";\nimport type { BlogAutoRevalidatePayload, RevalidatePathFn, RevalidateTagFn } from \"./types\";\n\nexport interface VerifyWebhookSignatureOptions {\n rawBody: string | Buffer;\n signature: string | null;\n secret: string;\n}\n\nexport interface CreateRevalidateRouteHandlerOptions {\n secret: string;\n allowedSkewSeconds?: number;\n revalidatePath?: RevalidatePathFn;\n revalidateTag?: RevalidateTagFn;\n revalidatePaths?: (payload: BlogAutoRevalidatePayload) => string[];\n revalidateTags?: (payload: BlogAutoRevalidatePayload) => string[];\n}\n\ninterface JsonResponseInit extends ResponseInit {\n status?: number;\n}\n\nfunction jsonResponse(body: unknown, init?: JsonResponseInit): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"content-type\", \"application/json\");\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeSignature(signature: string | null): Buffer | null {\n if (!signature) {\n return null;\n }\n const trimmed = signature.trim();\n if (!trimmed) {\n return null;\n }\n\n const withoutPrefix = trimmed.startsWith(\"sha256=\") ? trimmed.slice(7) : trimmed;\n if (!withoutPrefix) {\n return null;\n }\n\n try {\n return Buffer.from(withoutPrefix, \"hex\");\n } catch {\n return null;\n }\n}\n\nexport function verifyWebhookSignature(opts: VerifyWebhookSignatureOptions): boolean {\n const { rawBody, signature, secret } = opts;\n if (!secret) {\n throw new Error(\"Secret is required to verify webhook signatures\");\n }\n const providedSignature = normalizeSignature(signature);\n if (!providedSignature) {\n return false;\n }\n\n const bodyBuffer = typeof rawBody === \"string\" ? Buffer.from(rawBody) : rawBody;\n const expected = crypto.createHmac(\"sha256\", secret).update(bodyBuffer).digest();\n\n if (providedSignature.length !== expected.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedSignature, expected);\n}\n\nfunction defaultPaths(payload: BlogAutoRevalidatePayload): string[] {\n const paths = new Set<string>([\"/sitemap.xml\", \"/robots.txt\", \"/blog\"]);\n if (payload.postSlug) {\n paths.add(`/blog/${payload.postSlug}`);\n }\n return Array.from(paths);\n}\n\nfunction defaultTags(payload: BlogAutoRevalidatePayload): string[] {\n const tags = new Set<string>();\n if (payload.workspaceSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:sitemap`);\n tags.add(`blogauto:${payload.workspaceSlug}:posts`);\n if (payload.postSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:post:${payload.postSlug}`);\n }\n }\n return Array.from(tags);\n}\n\nfunction dedupe(values: string[] | undefined): string[] {\n if (!values || values.length === 0) {\n return [];\n }\n return Array.from(\n new Set(\n values\n .filter((value) => typeof value === \"string\" && value.trim().length > 0)\n .map((value) => value.trim()),\n ),\n );\n}\n\nfunction determineRouteType(path: string): \"route\" | \"page\" {\n const lower = path.toLowerCase();\n if (lower.endsWith(\".xml\") || lower.endsWith(\".txt\")) {\n return \"route\";\n }\n return \"page\";\n}\n\nexport function createRevalidateRouteHandler(\n options: CreateRevalidateRouteHandlerOptions,\n): (request: Request) => Promise<Response> {\n if (!options.secret) {\n throw new Error(\"secret is required for createRevalidateRouteHandler\");\n }\n\n const allowedSkewMs = Math.max(1, options.allowedSkewSeconds ?? 300) * 1000;\n const pathBuilder = options.revalidatePaths ?? defaultPaths;\n const tagBuilder = options.revalidateTags ?? defaultTags;\n\n return async function blogAutoRevalidateHandler(request: Request): Promise<Response> {\n const signature = request.headers.get(\"x-blogauto-signature\");\n const receivedAt = Date.now();\n\n const rawBody = await request.text();\n const isValid = verifyWebhookSignature({\n rawBody,\n signature,\n secret: options.secret,\n });\n\n if (!isValid) {\n return jsonResponse({ error: \"Invalid webhook signature\" }, { status: 401 });\n }\n\n let payload: BlogAutoRevalidatePayload;\n try {\n payload = JSON.parse(rawBody) as BlogAutoRevalidatePayload;\n } catch {\n return jsonResponse({ error: \"Invalid JSON payload\" }, { status: 400 });\n }\n\n if (!payload.workspaceSlug || typeof payload.workspaceSlug !== \"string\") {\n return jsonResponse({ error: \"workspaceSlug is required\" }, { status: 400 });\n }\n\n if (!payload.ts || typeof payload.ts !== \"string\") {\n return jsonResponse({ error: \"Timestamp is required\" }, { status: 400 });\n }\n\n const payloadTs = Date.parse(payload.ts);\n if (Number.isNaN(payloadTs)) {\n return jsonResponse({ error: \"Invalid timestamp\" }, { status: 400 });\n }\n\n if (Math.abs(receivedAt - payloadTs) > allowedSkewMs) {\n return jsonResponse({ error: \"Webhook timestamp is outside allowed skew\" }, { status: 409 });\n }\n\n const paths = dedupe(pathBuilder(payload));\n const tags = dedupe(tagBuilder(payload));\n\n try {\n if (options.revalidatePath && paths.length > 0) {\n await Promise.all(\n paths.map((path) => options.revalidatePath!(path, determineRouteType(path))),\n );\n }\n\n if (options.revalidateTag && tags.length > 0) {\n await Promise.all(tags.map((tag) => options.revalidateTag!(tag)));\n }\n } catch (error) {\n return jsonResponse(\n { error: \"Failed to revalidate cache\", details: (error as Error).message },\n { status: 500 },\n );\n }\n\n return jsonResponse({\n ok: true,\n event: payload.event ?? \"post.published\",\n revalidated: {\n paths,\n tags,\n },\n });\n };\n}\n","import type { BlogPost } from \"./types\";\n\nexport interface NextMetadata {\n title?: string;\n description?: string;\n keywords?: string[];\n alternates?: {\n canonical?: string;\n };\n openGraph?: {\n type?: string;\n title?: string;\n description?: string;\n images?: Array<{ url: string }>;\n publishedTime?: string;\n modifiedTime?: string;\n };\n twitter?: {\n card?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n}\n\nexport function buildNextMetadata(post: BlogPost): NextMetadata {\n const title = post.seo?.title ?? post.title;\n const description = post.seo?.description ?? post.excerpt;\n const keywords = post.seo?.keywords;\n const canonical = post.metadata?.canonicalUrl;\n const ogImageUrl = post.metadata?.ogImageUrl;\n\n const metadata: NextMetadata = {\n title,\n description,\n };\n\n if (keywords && keywords.length > 0) {\n metadata.keywords = keywords;\n }\n\n if (canonical) {\n metadata.alternates = { canonical };\n }\n\n metadata.openGraph = {\n type: \"article\",\n title,\n description,\n publishedTime: post.publishedAt,\n modifiedTime: post.updatedAt,\n };\n\n if (ogImageUrl) {\n metadata.openGraph.images = [{ url: ogImageUrl }];\n }\n\n metadata.twitter = {\n card: ogImageUrl ? \"summary_large_image\" : \"summary\",\n title,\n description,\n };\n\n if (ogImageUrl) {\n metadata.twitter.images = [ogImageUrl];\n }\n\n return metadata;\n}\n","import { createBlogAutoClient, type BlogAutoClient } from \"./client\";\n\nexport interface BlogAutoEnvConfig {\n client: BlogAutoClient;\n workspaceSlug: string;\n workspaceId?: string;\n siteUrl: string;\n revalidateSecret?: string;\n analyticsToken?: string;\n analyticsProxy: string;\n apiUrl: string;\n apiKey: string;\n tags: {\n posts: string;\n post: (slug: string) => string;\n sitemap: string;\n };\n}\n\nlet _instance: BlogAutoEnvConfig | null = null;\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\nexport function createBlogAutoFromEnv(): BlogAutoEnvConfig {\n if (_instance) {\n return _instance;\n }\n\n const apiUrl = process.env.BLOGAUTO_API_URL ?? \"https://api.blogauto.io\";\n const apiKey = requireEnv(\"BLOGAUTO_API_KEY\");\n const workspaceSlug = requireEnv(\"BLOGAUTO_WORKSPACE_SLUG\");\n const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;\n const siteUrl =\n process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? \"http://localhost:3000\";\n const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;\n const analyticsToken = process.env.NEXT_PUBLIC_ANALYTICS_TOKEN;\n const analyticsProxy =\n process.env.NEXT_PUBLIC_ANALYTICS_PROXY ?? \"/api/blogauto/analytics\";\n\n const client = createBlogAutoClient({\n apiUrl,\n apiKey,\n workspaceSlug,\n workspaceId,\n });\n\n _instance = {\n client,\n workspaceSlug,\n workspaceId,\n siteUrl,\n revalidateSecret,\n analyticsToken,\n analyticsProxy,\n apiUrl,\n apiKey,\n tags: {\n posts: `blogauto:${workspaceSlug}:posts`,\n post: (slug: string) => `blogauto:${workspaceSlug}:post:${slug}`,\n sitemap: `blogauto:${workspaceSlug}:sitemap`,\n },\n };\n\n return _instance;\n}\n"],"mappings":"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","names":["normalizeSiteUrl","crypto"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/auth.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/sitemap.ts","../src/robots.ts","../src/render.ts","../src/revalidate.ts","../src/metadata.ts","../src/env.ts"],"sourcesContent":["export { createBlogAutoClient } from \"./client\";\nexport type { BlogAutoClient } from \"./client\";\n\nexport { buildSitemap } from \"./sitemap\";\nexport { buildRobots } from \"./robots\";\nexport { renderMarkdownToHtml } from \"./render\";\nexport { verifyWebhookSignature, createRevalidateRouteHandler } from \"./revalidate\";\nexport { buildNextMetadata, type NextMetadata } from \"./metadata\";\n\nexport { buildAuthHeaders } from \"./auth\";\nexport { DEFAULT_TIMEOUT_MS, resolveClientConfig } from \"./utils\";\nexport { BlogAutoError, ConfigError, ApiError, NotFoundError } from \"./errors\";\nexport { createBlogAutoFromEnv, type BlogAutoEnvConfig } from \"./env\";\n\nexport type {\n BlogAutoClientConfig,\n BlogPost,\n BuildRobotsOptions,\n BuildSitemapOptions,\n MetadataRouteRobots,\n MetadataRouteSitemap,\n PaginatedList,\n PostsResponse,\n SitemapEntry,\n BlogAutoRevalidatePayload,\n RevalidatePathFn,\n RevalidateTagFn,\n FetchRequestOptions,\n FetchNextConfig,\n} from \"./types\";\n","import { AuthMode } from \"./types\";\n\nexport function buildAuthHeaders(apiKey: string, authMode: AuthMode = \"bearer\"): Record<string, string> {\n if (authMode === \"x-api-key\") {\n return { \"x-api-key\": apiKey };\n }\n return { Authorization: `Bearer ${apiKey}` };\n}\n","export class BlogAutoError extends Error {\n public readonly causeError?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = new.target.name;\n this.causeError = options?.cause;\n }\n}\n\nexport class ConfigError extends BlogAutoError {}\n\nexport interface ApiErrorDetails {\n status: number;\n code?: string;\n details?: unknown;\n}\n\nexport class ApiError extends BlogAutoError {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, info: ApiErrorDetails, options?: { cause?: unknown }) {\n super(message, options);\n this.status = info.status;\n this.code = info.code;\n this.details = info.details;\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, info?: Partial<ApiErrorDetails>) {\n super(message, { status: info?.status ?? 404, code: info?.code, details: info?.details });\n }\n}\n","import { ApiError, ConfigError } from \"./errors\";\nimport { AuthMode, BlogAutoClientConfig, InternalClientConfig } from \"./types\";\n\nexport const DEFAULT_TIMEOUT_MS = 10_000;\n\nexport function normalizeApiUrl(apiUrl: string): string {\n if (!apiUrl) {\n throw new ConfigError(\"apiUrl is required\");\n }\n\n return apiUrl.replace(/\\/$/, \"\");\n}\n\nexport function resolveClientConfig(config: BlogAutoClientConfig): InternalClientConfig {\n if (!config) {\n throw new ConfigError(\"Client configuration is required\");\n }\n\n const apiKey = config.apiKey?.trim();\n if (!apiKey) {\n throw new ConfigError(\"apiKey is required to authenticate with BlogAuto\");\n }\n\n if (!config.workspaceId && !config.workspaceSlug) {\n throw new ConfigError(\"Provide either workspaceId or workspaceSlug\");\n }\n\n const authMode: AuthMode = config.authMode ?? \"bearer\";\n\n return {\n apiKey,\n apiUrl: normalizeApiUrl(config.apiUrl),\n workspaceId: config.workspaceId,\n workspaceSlug: config.workspaceSlug,\n authMode,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n headers: { ...(config.headers ?? {}) },\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n };\n}\n\nexport function buildQuery(params: Record<string, string | number | undefined | null>): string {\n const query = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n query.set(key, String(value));\n });\n const qs = query.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T> {\n if (!timeoutMs) {\n return promise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new ApiError(`Request timed out after ${timeoutMs}ms`, {\n status: 408,\n }),\n );\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: Array<Record<string, string> | undefined>\n): Record<string, string> {\n return headerObjects.reduce<Record<string, string>>((acc, headers) => {\n if (!headers) {\n return acc;\n }\n Object.entries(headers).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n acc[key.toLowerCase()] = value;\n });\n return acc;\n }, {});\n}\n","import { buildAuthHeaders } from \"./auth\";\nimport { ApiError, BlogAutoError, ConfigError } from \"./errors\";\nimport { buildQuery, mergeHeaders, resolveClientConfig, withTimeout } from \"./utils\";\nimport type {\n BlogAutoClientConfig,\n BlogPost,\n FetchRequestOptions,\n PaginatedList,\n PostsResponse,\n} from \"./types\";\n\ninterface RequestOptions {\n path: string;\n method?: string;\n query?: Record<string, string | number | undefined | null>;\n body?: unknown;\n allowNotFound?: boolean;\n headers?: Record<string, string>;\n cache?: RequestCache;\n next?: FetchRequestOptions[\"next\"];\n}\n\nexport interface BlogAutoClient {\n getPosts(params?: { limit?: number; cursor?: string } & FetchRequestOptions): Promise<PostsResponse>;\n getPostBySlug(slug: string, options?: FetchRequestOptions): Promise<BlogPost | null>;\n getSitemapEntries(): Promise<Array<{ slug: string; updatedAt: string }>>;\n}\n\nexport function createBlogAutoClient(config: BlogAutoClientConfig): BlogAutoClient {\n const resolved = resolveClientConfig(config);\n const fetchImpl = resolved.fetch;\n const debug =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.BLOGAUTO_DEBUG === \"true\";\n const debugLog = (...args: unknown[]) => {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\"[blogauto]\", ...args);\n }\n };\n\n function ensureWorkspaceSlug(): string {\n if (!resolved.workspaceSlug) {\n throw new ConfigError(\"workspaceSlug is required to call the BlogAuto public API\");\n }\n return resolved.workspaceSlug;\n }\n\n function buildUrl(path: string, query?: Record<string, string | number | undefined | null>): string {\n const qs = buildQuery(query ?? {});\n return `${resolved.apiUrl}${path}${qs}`;\n }\n\n function unwrapSuccessPayload<T>(payload: unknown): T {\n if (payload && typeof payload === \"object\") {\n const maybePayload = payload as { success?: boolean; data?: T; error?: { message?: string } };\n if (\"success\" in maybePayload) {\n if (maybePayload.success === false) {\n throw new ApiError(\n maybePayload.error?.message ?? \"BlogAuto request failed\",\n { status: 500, details: maybePayload },\n );\n }\n if (maybePayload.success && \"data\" in maybePayload) {\n return maybePayload.data as T;\n }\n }\n }\n return payload as T;\n }\n\n async function request<T>(opts: RequestOptions): Promise<T> {\n const method = opts.method ?? \"GET\";\n const url = buildUrl(opts.path, opts.query);\n\n const authHeaders = buildAuthHeaders(resolved.apiKey, resolved.authMode);\n const baseHeaders = mergeHeaders(resolved.headers, authHeaders, opts.headers);\n\n const init: RequestInit = {\n method,\n headers: baseHeaders,\n };\n\n if (opts.body) {\n init.body = typeof opts.body === \"string\" ? opts.body : JSON.stringify(opts.body);\n init.headers = {\n ...baseHeaders,\n \"content-type\": baseHeaders[\"content-type\"] ?? \"application/json\",\n };\n }\n\n if (opts.cache !== undefined) {\n init.cache = opts.cache;\n }\n\n if (opts.next) {\n (init as RequestInit & { next?: FetchRequestOptions[\"next\"] }).next = opts.next;\n }\n\n const startedAt = Date.now();\n try {\n const response = await withTimeout(fetchImpl(url, init), resolved.timeoutMs);\n debugLog(\"response\", {\n method,\n url,\n status: response.status,\n durationMs: Date.now() - startedAt,\n });\n if (opts.allowNotFound && response.status === 404) {\n return null as T;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n const payload = isJson ? await response.json().catch(() => undefined) : await response.text();\n\n if (!response.ok) {\n if (response.status === 404 && opts.allowNotFound) {\n return null as T;\n }\n\n const errorBody = payload as any;\n const message =\n errorBody?.error?.message ?? errorBody?.message ?? `Request failed with status ${response.status}`;\n throw new ApiError(message, {\n status: response.status,\n code: errorBody?.error?.code ?? errorBody?.code,\n details: errorBody?.error?.details ?? errorBody,\n });\n }\n\n if (isJson) {\n return unwrapSuccessPayload<T>(payload);\n }\n\n return (payload as T) ?? (undefined as T);\n } catch (error) {\n debugLog(\"request failed\", {\n method,\n url,\n durationMs: Date.now() - startedAt,\n error: error instanceof Error ? error.message : error,\n });\n if (error instanceof BlogAutoError) {\n throw error;\n }\n const causeMessage =\n error instanceof Error ? error.message : typeof error === \"string\" ? error : undefined;\n const message = causeMessage\n ? `Network request to BlogAuto failed: ${causeMessage}`\n : \"Network request to BlogAuto failed\";\n throw new ApiError(\n message,\n {\n status: 0,\n details: { url, method },\n },\n { cause: error },\n );\n }\n }\n\n async function fetchBlogPage(\n limit: number,\n page: number,\n cacheOptions?: FetchRequestOptions,\n ): Promise<PaginatedList<BlogPost>> {\n const workspaceSlug = ensureWorkspaceSlug();\n debugLog(\"fetch posts page\", { workspaceSlug, limit, page });\n return request<PaginatedList<BlogPost>>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs`,\n query: { limit, page },\n cache: cacheOptions?.cache,\n next: cacheOptions?.next,\n });\n }\n\n return {\n async getPosts(params) {\n const limit = params?.limit ?? 20;\n const cursorPage = params?.cursor ? Number(params.cursor) : undefined;\n const page = Number.isFinite(cursorPage) && cursorPage! >= 1 ? cursorPage! : 1;\n const data = await fetchBlogPage(limit, page, params);\n return {\n posts: data.items,\n nextCursor: data.pagination.hasMore ? String(data.pagination.page + 1) : undefined,\n };\n },\n async getPostBySlug(slug: string, options?: FetchRequestOptions) {\n if (!slug) {\n throw new ApiError(\"slug is required\", { status: 400 });\n }\n const workspaceSlug = ensureWorkspaceSlug();\n const post = await request<{ post: BlogPost } | null>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs/${encodeURIComponent(slug)}`,\n allowNotFound: true,\n cache: options?.cache,\n next: options?.next,\n });\n if (post === null) {\n return null;\n }\n return post.post;\n },\n async getSitemapEntries() {\n const entries: Array<{ slug: string; updatedAt: string }> = [];\n const limit = 100;\n let page = 1;\n\n while (true) {\n const pageData = await fetchBlogPage(limit, page);\n pageData.items.forEach((post) => {\n entries.push({ slug: post.slug, updatedAt: post.updatedAt });\n });\n\n if (!pageData.pagination.hasMore) {\n break;\n }\n\n page = pageData.pagination.page + 1;\n }\n\n return entries;\n },\n };\n}\n","import { BuildSitemapOptions, MetadataRouteSitemap, MetadataRouteSitemapEntry } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizeRoutePrefix(routePrefix?: string): string {\n if (!routePrefix || routePrefix === \"/\") {\n return \"\";\n }\n const withSlash = routePrefix.startsWith(\"/\") ? routePrefix : `/${routePrefix}`;\n return withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash;\n}\n\nfunction normalizeSlug(slug: string): string {\n return slug.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function buildSitemap(opts: BuildSitemapOptions): MetadataRouteSitemap {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const prefix = normalizeRoutePrefix(opts.routePrefix ?? \"/blog\");\n\n const entries: MetadataRouteSitemapEntry[] = opts.entries.map((entry) => {\n const slug = normalizeSlug(entry.slug);\n const hasSlug = slug.length > 0;\n const slugFragment = hasSlug ? `/${slug}` : \"\";\n const path = prefix ? `${prefix}${slugFragment}` : hasSlug ? `/${slug}` : \"/\";\n return {\n url: `${siteUrl}${path}`,\n lastModified: entry.updatedAt,\n };\n });\n\n return entries;\n}\n","import { BuildRobotsOptions, MetadataRouteRobots } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n if (!path) {\n return \"/sitemap.xml\";\n }\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n return path;\n}\n\nexport function buildRobots(opts: BuildRobotsOptions): MetadataRouteRobots {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const sitemapPath = normalizePath(opts.sitemapPath ?? \"/sitemap.xml\");\n const sitemapUrl = `${siteUrl}${sitemapPath}`;\n\n return {\n rules: [{ userAgent: \"*\", allow: \"/\" }],\n sitemap: sitemapUrl,\n };\n}\n","const CODE_BLOCK_TOKEN = \"__BLOGAUTO_CODE_BLOCK_\";\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\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(/__BLOGAUTO_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 crypto from \"crypto\";\nimport type { BlogAutoRevalidatePayload, RevalidatePathFn, RevalidateTagFn } from \"./types\";\n\nexport interface VerifyWebhookSignatureOptions {\n rawBody: string | Buffer;\n signature: string | null;\n secret: string;\n}\n\nexport interface CreateRevalidateRouteHandlerOptions {\n secret: string;\n allowedSkewSeconds?: number;\n revalidatePath?: RevalidatePathFn;\n revalidateTag?: RevalidateTagFn;\n revalidatePaths?: (payload: BlogAutoRevalidatePayload) => string[];\n revalidateTags?: (payload: BlogAutoRevalidatePayload) => string[];\n}\n\ninterface JsonResponseInit extends ResponseInit {\n status?: number;\n}\n\nfunction jsonResponse(body: unknown, init?: JsonResponseInit): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"content-type\", \"application/json\");\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeSignature(signature: string | null): Buffer | null {\n if (!signature) {\n return null;\n }\n const trimmed = signature.trim();\n if (!trimmed) {\n return null;\n }\n\n const withoutPrefix = trimmed.startsWith(\"sha256=\") ? trimmed.slice(7) : trimmed;\n if (!withoutPrefix) {\n return null;\n }\n\n try {\n return Buffer.from(withoutPrefix, \"hex\");\n } catch {\n return null;\n }\n}\n\nexport function verifyWebhookSignature(opts: VerifyWebhookSignatureOptions): boolean {\n const { rawBody, signature, secret } = opts;\n if (!secret) {\n throw new Error(\"Secret is required to verify webhook signatures\");\n }\n const providedSignature = normalizeSignature(signature);\n if (!providedSignature) {\n return false;\n }\n\n const bodyBuffer = typeof rawBody === \"string\" ? Buffer.from(rawBody) : rawBody;\n const expected = crypto.createHmac(\"sha256\", secret).update(bodyBuffer).digest();\n\n if (providedSignature.length !== expected.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedSignature, expected);\n}\n\nfunction defaultPaths(payload: BlogAutoRevalidatePayload): string[] {\n const paths = new Set<string>([\"/sitemap.xml\", \"/robots.txt\", \"/blog\"]);\n if (payload.postSlug) {\n paths.add(`/blog/${payload.postSlug}`);\n }\n return Array.from(paths);\n}\n\nfunction defaultTags(payload: BlogAutoRevalidatePayload): string[] {\n const tags = new Set<string>();\n if (payload.workspaceSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:sitemap`);\n tags.add(`blogauto:${payload.workspaceSlug}:posts`);\n if (payload.postSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:post:${payload.postSlug}`);\n }\n }\n return Array.from(tags);\n}\n\nfunction dedupe(values: string[] | undefined): string[] {\n if (!values || values.length === 0) {\n return [];\n }\n return Array.from(\n new Set(\n values\n .filter((value) => typeof value === \"string\" && value.trim().length > 0)\n .map((value) => value.trim()),\n ),\n );\n}\n\nfunction determineRouteType(path: string): \"route\" | \"page\" {\n const lower = path.toLowerCase();\n if (lower.endsWith(\".xml\") || lower.endsWith(\".txt\")) {\n return \"route\";\n }\n return \"page\";\n}\n\nexport function createRevalidateRouteHandler(\n options: CreateRevalidateRouteHandlerOptions,\n): (request: Request) => Promise<Response> {\n if (!options.secret) {\n throw new Error(\"secret is required for createRevalidateRouteHandler\");\n }\n\n const allowedSkewMs = Math.max(1, options.allowedSkewSeconds ?? 300) * 1000;\n const pathBuilder = options.revalidatePaths ?? defaultPaths;\n const tagBuilder = options.revalidateTags ?? defaultTags;\n\n return async function blogAutoRevalidateHandler(request: Request): Promise<Response> {\n const signature = request.headers.get(\"x-blogauto-signature\");\n const receivedAt = Date.now();\n\n const rawBody = await request.text();\n const isValid = verifyWebhookSignature({\n rawBody,\n signature,\n secret: options.secret,\n });\n\n if (!isValid) {\n return jsonResponse({ error: \"Invalid webhook signature\" }, { status: 401 });\n }\n\n let payload: BlogAutoRevalidatePayload;\n try {\n payload = JSON.parse(rawBody) as BlogAutoRevalidatePayload;\n } catch {\n return jsonResponse({ error: \"Invalid JSON payload\" }, { status: 400 });\n }\n\n if (!payload.workspaceSlug || typeof payload.workspaceSlug !== \"string\") {\n return jsonResponse({ error: \"workspaceSlug is required\" }, { status: 400 });\n }\n\n if (!payload.ts || typeof payload.ts !== \"string\") {\n return jsonResponse({ error: \"Timestamp is required\" }, { status: 400 });\n }\n\n const payloadTs = Date.parse(payload.ts);\n if (Number.isNaN(payloadTs)) {\n return jsonResponse({ error: \"Invalid timestamp\" }, { status: 400 });\n }\n\n if (Math.abs(receivedAt - payloadTs) > allowedSkewMs) {\n return jsonResponse({ error: \"Webhook timestamp is outside allowed skew\" }, { status: 409 });\n }\n\n const paths = dedupe(pathBuilder(payload));\n const tags = dedupe(tagBuilder(payload));\n\n try {\n if (options.revalidatePath && paths.length > 0) {\n await Promise.all(\n paths.map((path) => options.revalidatePath!(path, determineRouteType(path))),\n );\n }\n\n if (options.revalidateTag && tags.length > 0) {\n await Promise.all(tags.map((tag) => options.revalidateTag!(tag)));\n }\n } catch (error) {\n return jsonResponse(\n { error: \"Failed to revalidate cache\", details: (error as Error).message },\n { status: 500 },\n );\n }\n\n return jsonResponse({\n ok: true,\n event: payload.event ?? \"post.published\",\n revalidated: {\n paths,\n tags,\n },\n });\n };\n}\n","import type { BlogPost } from \"./types\";\n\nexport interface NextMetadata {\n title?: string;\n description?: string;\n keywords?: string[];\n alternates?: {\n canonical?: string;\n };\n openGraph?: {\n type?: string;\n title?: string;\n description?: string;\n images?: Array<{ url: string }>;\n publishedTime?: string;\n modifiedTime?: string;\n };\n twitter?: {\n card?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n}\n\nexport function buildNextMetadata(post: BlogPost): NextMetadata {\n const title = post.seo?.title ?? post.title;\n const description = post.seo?.description ?? post.excerpt;\n const keywords = post.seo?.keywords;\n const canonical = post.metadata?.canonicalUrl;\n const ogImageUrl = post.metadata?.ogImageUrl;\n\n const metadata: NextMetadata = {\n title,\n description,\n };\n\n if (keywords && keywords.length > 0) {\n metadata.keywords = keywords;\n }\n\n if (canonical) {\n metadata.alternates = { canonical };\n }\n\n metadata.openGraph = {\n type: \"article\",\n title,\n description,\n publishedTime: post.publishedAt,\n modifiedTime: post.updatedAt,\n };\n\n if (ogImageUrl) {\n metadata.openGraph.images = [{ url: ogImageUrl }];\n }\n\n metadata.twitter = {\n card: ogImageUrl ? \"summary_large_image\" : \"summary\",\n title,\n description,\n };\n\n if (ogImageUrl) {\n metadata.twitter.images = [ogImageUrl];\n }\n\n return metadata;\n}\n","import { createBlogAutoClient, type BlogAutoClient } from \"./client\";\n\nexport interface BlogAutoEnvConfig {\n client: BlogAutoClient;\n workspaceSlug: string;\n workspaceId?: string;\n siteUrl: string;\n revalidateSecret?: string;\n apiUrl: string;\n apiKey: string;\n tags: {\n posts: string;\n post: (slug: string) => string;\n sitemap: string;\n };\n}\n\nlet _instance: BlogAutoEnvConfig | null = null;\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\nexport function createBlogAutoFromEnv(): BlogAutoEnvConfig {\n if (_instance) {\n return _instance;\n }\n\n const apiUrl = process.env.BLOGAUTO_API_URL ?? \"https://api.blogauto.io\";\n const apiKey = requireEnv(\"BLOGAUTO_API_KEY\");\n const workspaceSlug = requireEnv(\"BLOGAUTO_WORKSPACE_SLUG\");\n const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;\n const siteUrl =\n process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? \"http://localhost:3000\";\n const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;\n\n const client = createBlogAutoClient({\n apiUrl,\n apiKey,\n workspaceSlug,\n workspaceId,\n });\n\n _instance = {\n client,\n workspaceSlug,\n workspaceId,\n siteUrl,\n revalidateSecret,\n apiUrl,\n apiKey,\n tags: {\n posts: `blogauto:${workspaceSlug}:posts`,\n post: (slug: string) => `blogauto:${workspaceSlug}:post:${slug}`,\n sitemap: `blogauto:${workspaceSlug}:sitemap`,\n },\n };\n\n return _instance;\n}\n"],"mappings":"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","names":["normalizeSiteUrl","crypto"]}
package/dist/index.d.cts CHANGED
@@ -58,8 +58,6 @@ interface BlogAutoEnvConfig {
58
58
  workspaceId?: string;
59
59
  siteUrl: string;
60
60
  revalidateSecret?: string;
61
- analyticsToken?: string;
62
- analyticsProxy: string;
63
61
  apiUrl: string;
64
62
  apiKey: string;
65
63
  tags: {
package/dist/index.d.ts CHANGED
@@ -58,8 +58,6 @@ interface BlogAutoEnvConfig {
58
58
  workspaceId?: string;
59
59
  siteUrl: string;
60
60
  revalidateSecret?: string;
61
- analyticsToken?: string;
62
- analyticsProxy: string;
63
61
  apiUrl: string;
64
62
  apiKey: string;
65
63
  tags: {
package/dist/index.js CHANGED
@@ -589,8 +589,6 @@ function createBlogAutoFromEnv() {
589
589
  const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;
590
590
  const siteUrl = process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000";
591
591
  const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;
592
- const analyticsToken = process.env.NEXT_PUBLIC_ANALYTICS_TOKEN;
593
- const analyticsProxy = process.env.NEXT_PUBLIC_ANALYTICS_PROXY ?? "/api/blogauto/analytics";
594
592
  const client = createBlogAutoClient({
595
593
  apiUrl,
596
594
  apiKey,
@@ -603,8 +601,6 @@ function createBlogAutoFromEnv() {
603
601
  workspaceId,
604
602
  siteUrl,
605
603
  revalidateSecret,
606
- analyticsToken,
607
- analyticsProxy,
608
604
  apiUrl,
609
605
  apiKey,
610
606
  tags: {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/sitemap.ts","../src/robots.ts","../src/render.ts","../src/revalidate.ts","../src/metadata.ts","../src/env.ts"],"sourcesContent":["import { AuthMode } from \"./types\";\n\nexport function buildAuthHeaders(apiKey: string, authMode: AuthMode = \"bearer\"): Record<string, string> {\n if (authMode === \"x-api-key\") {\n return { \"x-api-key\": apiKey };\n }\n return { Authorization: `Bearer ${apiKey}` };\n}\n","export class BlogAutoError extends Error {\n public readonly causeError?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = new.target.name;\n this.causeError = options?.cause;\n }\n}\n\nexport class ConfigError extends BlogAutoError {}\n\nexport interface ApiErrorDetails {\n status: number;\n code?: string;\n details?: unknown;\n}\n\nexport class ApiError extends BlogAutoError {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, info: ApiErrorDetails, options?: { cause?: unknown }) {\n super(message, options);\n this.status = info.status;\n this.code = info.code;\n this.details = info.details;\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, info?: Partial<ApiErrorDetails>) {\n super(message, { status: info?.status ?? 404, code: info?.code, details: info?.details });\n }\n}\n","import { ApiError, ConfigError } from \"./errors\";\nimport { AuthMode, BlogAutoClientConfig, InternalClientConfig } from \"./types\";\n\nexport const DEFAULT_TIMEOUT_MS = 10_000;\n\nexport function normalizeApiUrl(apiUrl: string): string {\n if (!apiUrl) {\n throw new ConfigError(\"apiUrl is required\");\n }\n\n return apiUrl.replace(/\\/$/, \"\");\n}\n\nexport function resolveClientConfig(config: BlogAutoClientConfig): InternalClientConfig {\n if (!config) {\n throw new ConfigError(\"Client configuration is required\");\n }\n\n const apiKey = config.apiKey?.trim();\n if (!apiKey) {\n throw new ConfigError(\"apiKey is required to authenticate with BlogAuto\");\n }\n\n if (!config.workspaceId && !config.workspaceSlug) {\n throw new ConfigError(\"Provide either workspaceId or workspaceSlug\");\n }\n\n const authMode: AuthMode = config.authMode ?? \"bearer\";\n\n return {\n apiKey,\n apiUrl: normalizeApiUrl(config.apiUrl),\n workspaceId: config.workspaceId,\n workspaceSlug: config.workspaceSlug,\n authMode,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n headers: { ...(config.headers ?? {}) },\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n };\n}\n\nexport function buildQuery(params: Record<string, string | number | undefined | null>): string {\n const query = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n query.set(key, String(value));\n });\n const qs = query.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T> {\n if (!timeoutMs) {\n return promise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new ApiError(`Request timed out after ${timeoutMs}ms`, {\n status: 408,\n }),\n );\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: Array<Record<string, string> | undefined>\n): Record<string, string> {\n return headerObjects.reduce<Record<string, string>>((acc, headers) => {\n if (!headers) {\n return acc;\n }\n Object.entries(headers).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n acc[key.toLowerCase()] = value;\n });\n return acc;\n }, {});\n}\n","import { buildAuthHeaders } from \"./auth\";\nimport { ApiError, BlogAutoError, ConfigError } from \"./errors\";\nimport { buildQuery, mergeHeaders, resolveClientConfig, withTimeout } from \"./utils\";\nimport type {\n BlogAutoClientConfig,\n BlogPost,\n FetchRequestOptions,\n PaginatedList,\n PostsResponse,\n} from \"./types\";\n\ninterface RequestOptions {\n path: string;\n method?: string;\n query?: Record<string, string | number | undefined | null>;\n body?: unknown;\n allowNotFound?: boolean;\n headers?: Record<string, string>;\n cache?: RequestCache;\n next?: FetchRequestOptions[\"next\"];\n}\n\nexport interface BlogAutoClient {\n getPosts(params?: { limit?: number; cursor?: string } & FetchRequestOptions): Promise<PostsResponse>;\n getPostBySlug(slug: string, options?: FetchRequestOptions): Promise<BlogPost | null>;\n getSitemapEntries(): Promise<Array<{ slug: string; updatedAt: string }>>;\n}\n\nexport function createBlogAutoClient(config: BlogAutoClientConfig): BlogAutoClient {\n const resolved = resolveClientConfig(config);\n const fetchImpl = resolved.fetch;\n const debug =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.BLOGAUTO_DEBUG === \"true\";\n const debugLog = (...args: unknown[]) => {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\"[blogauto]\", ...args);\n }\n };\n\n function ensureWorkspaceSlug(): string {\n if (!resolved.workspaceSlug) {\n throw new ConfigError(\"workspaceSlug is required to call the BlogAuto public API\");\n }\n return resolved.workspaceSlug;\n }\n\n function buildUrl(path: string, query?: Record<string, string | number | undefined | null>): string {\n const qs = buildQuery(query ?? {});\n return `${resolved.apiUrl}${path}${qs}`;\n }\n\n function unwrapSuccessPayload<T>(payload: unknown): T {\n if (payload && typeof payload === \"object\") {\n const maybePayload = payload as { success?: boolean; data?: T; error?: { message?: string } };\n if (\"success\" in maybePayload) {\n if (maybePayload.success === false) {\n throw new ApiError(\n maybePayload.error?.message ?? \"BlogAuto request failed\",\n { status: 500, details: maybePayload },\n );\n }\n if (maybePayload.success && \"data\" in maybePayload) {\n return maybePayload.data as T;\n }\n }\n }\n return payload as T;\n }\n\n async function request<T>(opts: RequestOptions): Promise<T> {\n const method = opts.method ?? \"GET\";\n const url = buildUrl(opts.path, opts.query);\n\n const authHeaders = buildAuthHeaders(resolved.apiKey, resolved.authMode);\n const baseHeaders = mergeHeaders(resolved.headers, authHeaders, opts.headers);\n\n const init: RequestInit = {\n method,\n headers: baseHeaders,\n };\n\n if (opts.body) {\n init.body = typeof opts.body === \"string\" ? opts.body : JSON.stringify(opts.body);\n init.headers = {\n ...baseHeaders,\n \"content-type\": baseHeaders[\"content-type\"] ?? \"application/json\",\n };\n }\n\n if (opts.cache !== undefined) {\n init.cache = opts.cache;\n }\n\n if (opts.next) {\n (init as RequestInit & { next?: FetchRequestOptions[\"next\"] }).next = opts.next;\n }\n\n const startedAt = Date.now();\n try {\n const response = await withTimeout(fetchImpl(url, init), resolved.timeoutMs);\n debugLog(\"response\", {\n method,\n url,\n status: response.status,\n durationMs: Date.now() - startedAt,\n });\n if (opts.allowNotFound && response.status === 404) {\n return null as T;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n const payload = isJson ? await response.json().catch(() => undefined) : await response.text();\n\n if (!response.ok) {\n if (response.status === 404 && opts.allowNotFound) {\n return null as T;\n }\n\n const errorBody = payload as any;\n const message =\n errorBody?.error?.message ?? errorBody?.message ?? `Request failed with status ${response.status}`;\n throw new ApiError(message, {\n status: response.status,\n code: errorBody?.error?.code ?? errorBody?.code,\n details: errorBody?.error?.details ?? errorBody,\n });\n }\n\n if (isJson) {\n return unwrapSuccessPayload<T>(payload);\n }\n\n return (payload as T) ?? (undefined as T);\n } catch (error) {\n debugLog(\"request failed\", {\n method,\n url,\n durationMs: Date.now() - startedAt,\n error: error instanceof Error ? error.message : error,\n });\n if (error instanceof BlogAutoError) {\n throw error;\n }\n const causeMessage =\n error instanceof Error ? error.message : typeof error === \"string\" ? error : undefined;\n const message = causeMessage\n ? `Network request to BlogAuto failed: ${causeMessage}`\n : \"Network request to BlogAuto failed\";\n throw new ApiError(\n message,\n {\n status: 0,\n details: { url, method },\n },\n { cause: error },\n );\n }\n }\n\n async function fetchBlogPage(\n limit: number,\n page: number,\n cacheOptions?: FetchRequestOptions,\n ): Promise<PaginatedList<BlogPost>> {\n const workspaceSlug = ensureWorkspaceSlug();\n debugLog(\"fetch posts page\", { workspaceSlug, limit, page });\n return request<PaginatedList<BlogPost>>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs`,\n query: { limit, page },\n cache: cacheOptions?.cache,\n next: cacheOptions?.next,\n });\n }\n\n return {\n async getPosts(params) {\n const limit = params?.limit ?? 20;\n const cursorPage = params?.cursor ? Number(params.cursor) : undefined;\n const page = Number.isFinite(cursorPage) && cursorPage! >= 1 ? cursorPage! : 1;\n const data = await fetchBlogPage(limit, page, params);\n return {\n posts: data.items,\n nextCursor: data.pagination.hasMore ? String(data.pagination.page + 1) : undefined,\n };\n },\n async getPostBySlug(slug: string, options?: FetchRequestOptions) {\n if (!slug) {\n throw new ApiError(\"slug is required\", { status: 400 });\n }\n const workspaceSlug = ensureWorkspaceSlug();\n const post = await request<{ post: BlogPost } | null>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs/${encodeURIComponent(slug)}`,\n allowNotFound: true,\n cache: options?.cache,\n next: options?.next,\n });\n if (post === null) {\n return null;\n }\n return post.post;\n },\n async getSitemapEntries() {\n const entries: Array<{ slug: string; updatedAt: string }> = [];\n const limit = 100;\n let page = 1;\n\n while (true) {\n const pageData = await fetchBlogPage(limit, page);\n pageData.items.forEach((post) => {\n entries.push({ slug: post.slug, updatedAt: post.updatedAt });\n });\n\n if (!pageData.pagination.hasMore) {\n break;\n }\n\n page = pageData.pagination.page + 1;\n }\n\n return entries;\n },\n };\n}\n","import { BuildSitemapOptions, MetadataRouteSitemap, MetadataRouteSitemapEntry } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizeRoutePrefix(routePrefix?: string): string {\n if (!routePrefix || routePrefix === \"/\") {\n return \"\";\n }\n const withSlash = routePrefix.startsWith(\"/\") ? routePrefix : `/${routePrefix}`;\n return withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash;\n}\n\nfunction normalizeSlug(slug: string): string {\n return slug.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function buildSitemap(opts: BuildSitemapOptions): MetadataRouteSitemap {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const prefix = normalizeRoutePrefix(opts.routePrefix ?? \"/blog\");\n\n const entries: MetadataRouteSitemapEntry[] = opts.entries.map((entry) => {\n const slug = normalizeSlug(entry.slug);\n const hasSlug = slug.length > 0;\n const slugFragment = hasSlug ? `/${slug}` : \"\";\n const path = prefix ? `${prefix}${slugFragment}` : hasSlug ? `/${slug}` : \"/\";\n return {\n url: `${siteUrl}${path}`,\n lastModified: entry.updatedAt,\n };\n });\n\n return entries;\n}\n","import { BuildRobotsOptions, MetadataRouteRobots } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n if (!path) {\n return \"/sitemap.xml\";\n }\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n return path;\n}\n\nexport function buildRobots(opts: BuildRobotsOptions): MetadataRouteRobots {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const sitemapPath = normalizePath(opts.sitemapPath ?? \"/sitemap.xml\");\n const sitemapUrl = `${siteUrl}${sitemapPath}`;\n\n return {\n rules: [{ userAgent: \"*\", allow: \"/\" }],\n sitemap: sitemapUrl,\n };\n}\n","const CODE_BLOCK_TOKEN = \"__BLOGAUTO_CODE_BLOCK_\";\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\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(/__BLOGAUTO_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 crypto from \"crypto\";\nimport type { BlogAutoRevalidatePayload, RevalidatePathFn, RevalidateTagFn } from \"./types\";\n\nexport interface VerifyWebhookSignatureOptions {\n rawBody: string | Buffer;\n signature: string | null;\n secret: string;\n}\n\nexport interface CreateRevalidateRouteHandlerOptions {\n secret: string;\n allowedSkewSeconds?: number;\n revalidatePath?: RevalidatePathFn;\n revalidateTag?: RevalidateTagFn;\n revalidatePaths?: (payload: BlogAutoRevalidatePayload) => string[];\n revalidateTags?: (payload: BlogAutoRevalidatePayload) => string[];\n}\n\ninterface JsonResponseInit extends ResponseInit {\n status?: number;\n}\n\nfunction jsonResponse(body: unknown, init?: JsonResponseInit): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"content-type\", \"application/json\");\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeSignature(signature: string | null): Buffer | null {\n if (!signature) {\n return null;\n }\n const trimmed = signature.trim();\n if (!trimmed) {\n return null;\n }\n\n const withoutPrefix = trimmed.startsWith(\"sha256=\") ? trimmed.slice(7) : trimmed;\n if (!withoutPrefix) {\n return null;\n }\n\n try {\n return Buffer.from(withoutPrefix, \"hex\");\n } catch {\n return null;\n }\n}\n\nexport function verifyWebhookSignature(opts: VerifyWebhookSignatureOptions): boolean {\n const { rawBody, signature, secret } = opts;\n if (!secret) {\n throw new Error(\"Secret is required to verify webhook signatures\");\n }\n const providedSignature = normalizeSignature(signature);\n if (!providedSignature) {\n return false;\n }\n\n const bodyBuffer = typeof rawBody === \"string\" ? Buffer.from(rawBody) : rawBody;\n const expected = crypto.createHmac(\"sha256\", secret).update(bodyBuffer).digest();\n\n if (providedSignature.length !== expected.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedSignature, expected);\n}\n\nfunction defaultPaths(payload: BlogAutoRevalidatePayload): string[] {\n const paths = new Set<string>([\"/sitemap.xml\", \"/robots.txt\", \"/blog\"]);\n if (payload.postSlug) {\n paths.add(`/blog/${payload.postSlug}`);\n }\n return Array.from(paths);\n}\n\nfunction defaultTags(payload: BlogAutoRevalidatePayload): string[] {\n const tags = new Set<string>();\n if (payload.workspaceSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:sitemap`);\n tags.add(`blogauto:${payload.workspaceSlug}:posts`);\n if (payload.postSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:post:${payload.postSlug}`);\n }\n }\n return Array.from(tags);\n}\n\nfunction dedupe(values: string[] | undefined): string[] {\n if (!values || values.length === 0) {\n return [];\n }\n return Array.from(\n new Set(\n values\n .filter((value) => typeof value === \"string\" && value.trim().length > 0)\n .map((value) => value.trim()),\n ),\n );\n}\n\nfunction determineRouteType(path: string): \"route\" | \"page\" {\n const lower = path.toLowerCase();\n if (lower.endsWith(\".xml\") || lower.endsWith(\".txt\")) {\n return \"route\";\n }\n return \"page\";\n}\n\nexport function createRevalidateRouteHandler(\n options: CreateRevalidateRouteHandlerOptions,\n): (request: Request) => Promise<Response> {\n if (!options.secret) {\n throw new Error(\"secret is required for createRevalidateRouteHandler\");\n }\n\n const allowedSkewMs = Math.max(1, options.allowedSkewSeconds ?? 300) * 1000;\n const pathBuilder = options.revalidatePaths ?? defaultPaths;\n const tagBuilder = options.revalidateTags ?? defaultTags;\n\n return async function blogAutoRevalidateHandler(request: Request): Promise<Response> {\n const signature = request.headers.get(\"x-blogauto-signature\");\n const receivedAt = Date.now();\n\n const rawBody = await request.text();\n const isValid = verifyWebhookSignature({\n rawBody,\n signature,\n secret: options.secret,\n });\n\n if (!isValid) {\n return jsonResponse({ error: \"Invalid webhook signature\" }, { status: 401 });\n }\n\n let payload: BlogAutoRevalidatePayload;\n try {\n payload = JSON.parse(rawBody) as BlogAutoRevalidatePayload;\n } catch {\n return jsonResponse({ error: \"Invalid JSON payload\" }, { status: 400 });\n }\n\n if (!payload.workspaceSlug || typeof payload.workspaceSlug !== \"string\") {\n return jsonResponse({ error: \"workspaceSlug is required\" }, { status: 400 });\n }\n\n if (!payload.ts || typeof payload.ts !== \"string\") {\n return jsonResponse({ error: \"Timestamp is required\" }, { status: 400 });\n }\n\n const payloadTs = Date.parse(payload.ts);\n if (Number.isNaN(payloadTs)) {\n return jsonResponse({ error: \"Invalid timestamp\" }, { status: 400 });\n }\n\n if (Math.abs(receivedAt - payloadTs) > allowedSkewMs) {\n return jsonResponse({ error: \"Webhook timestamp is outside allowed skew\" }, { status: 409 });\n }\n\n const paths = dedupe(pathBuilder(payload));\n const tags = dedupe(tagBuilder(payload));\n\n try {\n if (options.revalidatePath && paths.length > 0) {\n await Promise.all(\n paths.map((path) => options.revalidatePath!(path, determineRouteType(path))),\n );\n }\n\n if (options.revalidateTag && tags.length > 0) {\n await Promise.all(tags.map((tag) => options.revalidateTag!(tag)));\n }\n } catch (error) {\n return jsonResponse(\n { error: \"Failed to revalidate cache\", details: (error as Error).message },\n { status: 500 },\n );\n }\n\n return jsonResponse({\n ok: true,\n event: payload.event ?? \"post.published\",\n revalidated: {\n paths,\n tags,\n },\n });\n };\n}\n","import type { BlogPost } from \"./types\";\n\nexport interface NextMetadata {\n title?: string;\n description?: string;\n keywords?: string[];\n alternates?: {\n canonical?: string;\n };\n openGraph?: {\n type?: string;\n title?: string;\n description?: string;\n images?: Array<{ url: string }>;\n publishedTime?: string;\n modifiedTime?: string;\n };\n twitter?: {\n card?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n}\n\nexport function buildNextMetadata(post: BlogPost): NextMetadata {\n const title = post.seo?.title ?? post.title;\n const description = post.seo?.description ?? post.excerpt;\n const keywords = post.seo?.keywords;\n const canonical = post.metadata?.canonicalUrl;\n const ogImageUrl = post.metadata?.ogImageUrl;\n\n const metadata: NextMetadata = {\n title,\n description,\n };\n\n if (keywords && keywords.length > 0) {\n metadata.keywords = keywords;\n }\n\n if (canonical) {\n metadata.alternates = { canonical };\n }\n\n metadata.openGraph = {\n type: \"article\",\n title,\n description,\n publishedTime: post.publishedAt,\n modifiedTime: post.updatedAt,\n };\n\n if (ogImageUrl) {\n metadata.openGraph.images = [{ url: ogImageUrl }];\n }\n\n metadata.twitter = {\n card: ogImageUrl ? \"summary_large_image\" : \"summary\",\n title,\n description,\n };\n\n if (ogImageUrl) {\n metadata.twitter.images = [ogImageUrl];\n }\n\n return metadata;\n}\n","import { createBlogAutoClient, type BlogAutoClient } from \"./client\";\n\nexport interface BlogAutoEnvConfig {\n client: BlogAutoClient;\n workspaceSlug: string;\n workspaceId?: string;\n siteUrl: string;\n revalidateSecret?: string;\n analyticsToken?: string;\n analyticsProxy: string;\n apiUrl: string;\n apiKey: string;\n tags: {\n posts: string;\n post: (slug: string) => string;\n sitemap: string;\n };\n}\n\nlet _instance: BlogAutoEnvConfig | null = null;\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\nexport function createBlogAutoFromEnv(): BlogAutoEnvConfig {\n if (_instance) {\n return _instance;\n }\n\n const apiUrl = process.env.BLOGAUTO_API_URL ?? \"https://api.blogauto.io\";\n const apiKey = requireEnv(\"BLOGAUTO_API_KEY\");\n const workspaceSlug = requireEnv(\"BLOGAUTO_WORKSPACE_SLUG\");\n const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;\n const siteUrl =\n process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? \"http://localhost:3000\";\n const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;\n const analyticsToken = process.env.NEXT_PUBLIC_ANALYTICS_TOKEN;\n const analyticsProxy =\n process.env.NEXT_PUBLIC_ANALYTICS_PROXY ?? \"/api/blogauto/analytics\";\n\n const client = createBlogAutoClient({\n apiUrl,\n apiKey,\n workspaceSlug,\n workspaceId,\n });\n\n _instance = {\n client,\n workspaceSlug,\n workspaceId,\n siteUrl,\n revalidateSecret,\n analyticsToken,\n analyticsProxy,\n apiUrl,\n apiKey,\n tags: {\n posts: `blogauto:${workspaceSlug}:posts`,\n post: (slug: string) => `blogauto:${workspaceSlug}:post:${slug}`,\n sitemap: `blogauto:${workspaceSlug}:sitemap`,\n },\n };\n\n return _instance;\n}\n"],"mappings":";AAEO,SAAS,iBAAiB,QAAgB,WAAqB,UAAkC;AACtG,MAAI,aAAa,aAAa;AAC5B,WAAO,EAAE,aAAa,OAAO;AAAA,EAC/B;AACA,SAAO,EAAE,eAAe,UAAU,MAAM,GAAG;AAC7C;;;ACPO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EAGvC,YAAY,SAAiB,SAA+B;AAC1D,UAAM,OAAO;AACb,SAAK,OAAO,WAAW;AACvB,SAAK,aAAa,SAAS;AAAA,EAC7B;AACF;AAEO,IAAM,cAAN,cAA0B,cAAc;AAAC;AAQzC,IAAM,WAAN,cAAuB,cAAc;AAAA,EAK1C,YAAY,SAAiB,MAAuB,SAA+B;AACjF,UAAM,SAAS,OAAO;AACtB,SAAK,SAAS,KAAK;AACnB,SAAK,OAAO,KAAK;AACjB,SAAK,UAAU,KAAK;AAAA,EACtB;AACF;AAEO,IAAM,gBAAN,cAA4B,SAAS;AAAA,EAC1C,YAAY,SAAiB,MAAiC;AAC5D,UAAM,SAAS,EAAE,QAAQ,MAAM,UAAU,KAAK,MAAM,MAAM,MAAM,SAAS,MAAM,QAAQ,CAAC;AAAA,EAC1F;AACF;;;AChCO,IAAM,qBAAqB;AAE3B,SAAS,gBAAgB,QAAwB;AACtD,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,YAAY,oBAAoB;AAAA,EAC5C;AAEA,SAAO,OAAO,QAAQ,OAAO,EAAE;AACjC;AAEO,SAAS,oBAAoB,QAAoD;AACtF,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,YAAY,kCAAkC;AAAA,EAC1D;AAEA,QAAM,SAAS,OAAO,QAAQ,KAAK;AACnC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,YAAY,kDAAkD;AAAA,EAC1E;AAEA,MAAI,CAAC,OAAO,eAAe,CAAC,OAAO,eAAe;AAChD,UAAM,IAAI,YAAY,6CAA6C;AAAA,EACrE;AAEA,QAAM,WAAqB,OAAO,YAAY;AAE9C,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,gBAAgB,OAAO,MAAM;AAAA,IACrC,aAAa,OAAO;AAAA,IACpB,eAAe,OAAO;AAAA,IACtB;AAAA,IACA,OAAO,OAAO,SAAS,WAAW,MAAM,KAAK,UAAU;AAAA,IACvD,SAAS,EAAE,GAAI,OAAO,WAAW,CAAC,EAAG;AAAA,IACrC,WAAW,OAAO,aAAa;AAAA,EACjC;AACF;AAEO,SAAS,WAAW,QAAoE;AAC7F,QAAM,QAAQ,IAAI,gBAAgB;AAClC,SAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/C,QAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AACzD;AAAA,IACF;AACA,UAAM,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,EAC9B,CAAC;AACD,QAAM,KAAK,MAAM,SAAS;AAC1B,SAAO,KAAK,IAAI,EAAE,KAAK;AACzB;AAEA,eAAsB,YAAe,SAAqB,WAAgC;AACxF,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AAEA,MAAI;AAEJ,QAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,gBAAY,WAAW,MAAM;AAC3B;AAAA,QACE,IAAI,SAAS,2BAA2B,SAAS,MAAM;AAAA,UACrD,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF,GAAG,SAAS;AAAA,EACd,CAAC;AAED,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,cAAc,CAAC;AAAA,EACrD,UAAE;AACA,iBAAa,SAAU;AAAA,EACzB;AACF;AAEO,SAAS,gBACX,eACqB;AACxB,SAAO,cAAc,OAA+B,CAAC,KAAK,YAAY;AACpE,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,OAAO,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAChD,UAAI,UAAU,UAAa,UAAU,MAAM;AACzC;AAAA,MACF;AACA,UAAI,IAAI,YAAY,CAAC,IAAI;AAAA,IAC3B,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACP;;;AChEO,SAAS,qBAAqB,QAA8C;AACjF,QAAM,WAAW,oBAAoB,MAAM;AAC3C,QAAM,YAAY,SAAS;AAC3B,QAAM,QACJ,OAAO,YAAY,eACnB,OAAO,QAAQ,QAAQ,eACvB,QAAQ,IAAI,mBAAmB;AACjC,QAAM,WAAW,IAAI,SAAoB;AACvC,QAAI,OAAO;AAET,cAAQ,IAAI,cAAc,GAAG,IAAI;AAAA,IACnC;AAAA,EACF;AAEA,WAAS,sBAA8B;AACrC,QAAI,CAAC,SAAS,eAAe;AAC3B,YAAM,IAAI,YAAY,2DAA2D;AAAA,IACnF;AACA,WAAO,SAAS;AAAA,EAClB;AAEA,WAAS,SAAS,MAAc,OAAoE;AAClG,UAAM,KAAK,WAAW,SAAS,CAAC,CAAC;AACjC,WAAO,GAAG,SAAS,MAAM,GAAG,IAAI,GAAG,EAAE;AAAA,EACvC;AAEA,WAAS,qBAAwB,SAAqB;AACpD,QAAI,WAAW,OAAO,YAAY,UAAU;AAC1C,YAAM,eAAe;AACrB,UAAI,aAAa,cAAc;AAC7B,YAAI,aAAa,YAAY,OAAO;AAClC,gBAAM,IAAI;AAAA,YACR,aAAa,OAAO,WAAW;AAAA,YAC/B,EAAE,QAAQ,KAAK,SAAS,aAAa;AAAA,UACvC;AAAA,QACF;AACA,YAAI,aAAa,WAAW,UAAU,cAAc;AAClD,iBAAO,aAAa;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,iBAAe,QAAW,MAAkC;AAC1D,UAAM,SAAS,KAAK,UAAU;AAC9B,UAAM,MAAM,SAAS,KAAK,MAAM,KAAK,KAAK;AAE1C,UAAM,cAAc,iBAAiB,SAAS,QAAQ,SAAS,QAAQ;AACvE,UAAM,cAAc,aAAa,SAAS,SAAS,aAAa,KAAK,OAAO;AAE5E,UAAM,OAAoB;AAAA,MACxB;AAAA,MACA,SAAS;AAAA,IACX;AAEA,QAAI,KAAK,MAAM;AACb,WAAK,OAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,KAAK,UAAU,KAAK,IAAI;AAChF,WAAK,UAAU;AAAA,QACb,GAAG;AAAA,QACH,gBAAgB,YAAY,cAAc,KAAK;AAAA,MACjD;AAAA,IACF;AAEA,QAAI,KAAK,UAAU,QAAW;AAC5B,WAAK,QAAQ,KAAK;AAAA,IACpB;AAEA,QAAI,KAAK,MAAM;AACb,MAAC,KAA8D,OAAO,KAAK;AAAA,IAC7E;AAEA,UAAM,YAAY,KAAK,IAAI;AAC3B,QAAI;AACF,YAAM,WAAW,MAAM,YAAY,UAAU,KAAK,IAAI,GAAG,SAAS,SAAS;AAC3E,eAAS,YAAY;AAAA,QACnB;AAAA,QACA;AAAA,QACA,QAAQ,SAAS;AAAA,QACjB,YAAY,KAAK,IAAI,IAAI;AAAA,MAC3B,CAAC;AACD,UAAI,KAAK,iBAAiB,SAAS,WAAW,KAAK;AACjD,eAAO;AAAA,MACT;AAEA,YAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,YAAM,SAAS,YAAY,SAAS,kBAAkB;AACtD,YAAM,UAAU,SAAS,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,MAAS,IAAI,MAAM,SAAS,KAAK;AAE5F,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI,SAAS,WAAW,OAAO,KAAK,eAAe;AACjD,iBAAO;AAAA,QACT;AAEA,cAAM,YAAY;AAClB,cAAM,UACJ,WAAW,OAAO,WAAW,WAAW,WAAW,8BAA8B,SAAS,MAAM;AAClG,cAAM,IAAI,SAAS,SAAS;AAAA,UAC1B,QAAQ,SAAS;AAAA,UACjB,MAAM,WAAW,OAAO,QAAQ,WAAW;AAAA,UAC3C,SAAS,WAAW,OAAO,WAAW;AAAA,QACxC,CAAC;AAAA,MACH;AAEA,UAAI,QAAQ;AACV,eAAO,qBAAwB,OAAO;AAAA,MACxC;AAEA,aAAQ,WAAkB;AAAA,IAC5B,SAAS,OAAO;AACd,eAAS,kBAAkB;AAAA,QACzB;AAAA,QACA;AAAA,QACA,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAClD,CAAC;AACD,UAAI,iBAAiB,eAAe;AAClC,cAAM;AAAA,MACR;AACA,YAAM,eACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,UAAU,WAAW,QAAQ;AAC/E,YAAM,UAAU,eACZ,uCAAuC,YAAY,KACnD;AACJ,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,SAAS,EAAE,KAAK,OAAO;AAAA,QACzB;AAAA,QACA,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,iBAAe,cACb,OACA,MACA,cACkC;AAClC,UAAM,gBAAgB,oBAAoB;AAC1C,aAAS,oBAAoB,EAAE,eAAe,OAAO,KAAK,CAAC;AAC3D,WAAO,QAAiC;AAAA,MACtC,MAAM,cAAc,mBAAmB,aAAa,CAAC;AAAA,MACrD,OAAO,EAAE,OAAO,KAAK;AAAA,MACrB,OAAO,cAAc;AAAA,MACrB,MAAM,cAAc;AAAA,IACtB,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,MAAM,SAAS,QAAQ;AACrB,YAAM,QAAQ,QAAQ,SAAS;AAC/B,YAAM,aAAa,QAAQ,SAAS,OAAO,OAAO,MAAM,IAAI;AAC5D,YAAM,OAAO,OAAO,SAAS,UAAU,KAAK,cAAe,IAAI,aAAc;AAC7E,YAAM,OAAO,MAAM,cAAc,OAAO,MAAM,MAAM;AACpD,aAAO;AAAA,QACL,OAAO,KAAK;AAAA,QACZ,YAAY,KAAK,WAAW,UAAU,OAAO,KAAK,WAAW,OAAO,CAAC,IAAI;AAAA,MAC3E;AAAA,IACF;AAAA,IACA,MAAM,cAAc,MAAc,SAA+B;AAC/D,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,SAAS,oBAAoB,EAAE,QAAQ,IAAI,CAAC;AAAA,MACxD;AACA,YAAM,gBAAgB,oBAAoB;AAC1C,YAAM,OAAO,MAAM,QAAmC;AAAA,QACpD,MAAM,cAAc,mBAAmB,aAAa,CAAC,UAAU,mBAAmB,IAAI,CAAC;AAAA,QACvF,eAAe;AAAA,QACf,OAAO,SAAS;AAAA,QAChB,MAAM,SAAS;AAAA,MACjB,CAAC;AACD,UAAI,SAAS,MAAM;AACjB,eAAO;AAAA,MACT;AACA,aAAO,KAAK;AAAA,IACd;AAAA,IACA,MAAM,oBAAoB;AACxB,YAAM,UAAsD,CAAC;AAC7D,YAAM,QAAQ;AACd,UAAI,OAAO;AAEX,aAAO,MAAM;AACX,cAAM,WAAW,MAAM,cAAc,OAAO,IAAI;AAChD,iBAAS,MAAM,QAAQ,CAAC,SAAS;AAC/B,kBAAQ,KAAK,EAAE,MAAM,KAAK,MAAM,WAAW,KAAK,UAAU,CAAC;AAAA,QAC7D,CAAC;AAED,YAAI,CAAC,SAAS,WAAW,SAAS;AAChC;AAAA,QACF;AAEA,eAAO,SAAS,WAAW,OAAO;AAAA,MACpC;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AChOA,SAAS,iBAAiB,KAAqB;AAC7C,SAAO,IAAI,QAAQ,OAAO,EAAE;AAC9B;AAEA,SAAS,qBAAqB,aAA8B;AAC1D,MAAI,CAAC,eAAe,gBAAgB,KAAK;AACvC,WAAO;AAAA,EACT;AACA,QAAM,YAAY,YAAY,WAAW,GAAG,IAAI,cAAc,IAAI,WAAW;AAC7E,SAAO,UAAU,SAAS,GAAG,IAAI,UAAU,MAAM,GAAG,EAAE,IAAI;AAC5D;AAEA,SAAS,cAAc,MAAsB;AAC3C,SAAO,KAAK,QAAQ,QAAQ,EAAE,EAAE,QAAQ,QAAQ,EAAE;AACpD;AAEO,SAAS,aAAa,MAAiD;AAC5E,QAAM,UAAU,iBAAiB,KAAK,OAAO;AAC7C,QAAM,SAAS,qBAAqB,KAAK,eAAe,OAAO;AAE/D,QAAM,UAAuC,KAAK,QAAQ,IAAI,CAAC,UAAU;AACvE,UAAM,OAAO,cAAc,MAAM,IAAI;AACrC,UAAM,UAAU,KAAK,SAAS;AAC9B,UAAM,eAAe,UAAU,IAAI,IAAI,KAAK;AAC5C,UAAM,OAAO,SAAS,GAAG,MAAM,GAAG,YAAY,KAAK,UAAU,IAAI,IAAI,KAAK;AAC1E,WAAO;AAAA,MACL,KAAK,GAAG,OAAO,GAAG,IAAI;AAAA,MACtB,cAAc,MAAM;AAAA,IACtB;AAAA,EACF,CAAC;AAED,SAAO;AACT;;;AChCA,SAASA,kBAAiB,KAAqB;AAC7C,SAAO,IAAI,QAAQ,OAAO,EAAE;AAC9B;AAEA,SAAS,cAAc,MAAsB;AAC3C,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,MAAI,CAAC,KAAK,WAAW,GAAG,GAAG;AACzB,WAAO,IAAI,IAAI;AAAA,EACjB;AACA,SAAO;AACT;AAEO,SAAS,YAAY,MAA+C;AACzE,QAAM,UAAUA,kBAAiB,KAAK,OAAO;AAC7C,QAAM,cAAc,cAAc,KAAK,eAAe,cAAc;AACpE,QAAM,aAAa,GAAG,OAAO,GAAG,WAAW;AAE3C,SAAO;AAAA,IACL,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,IAAI,CAAC;AAAA,IACtC,SAAS;AAAA,EACX;AACF;;;ACzBA,IAAM,mBAAmB;AAEzB,SAAS,WAAW,OAAuB;AACzC,SAAO,MACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,OAAO;AAC1B;AAEA,SAAS,aAAa,OAAuB;AAC3C,MAAI,SAAS,WAAW,KAAK;AAC7B,WAAS,OAAO,QAAQ,kBAAkB,qBAAqB;AAC/D,WAAS,OAAO,QAAQ,cAAc,aAAa;AACnD,WAAS,OAAO,QAAQ,cAAc,CAAC,GAAG,SAAS,SAAS,IAAI,SAAS;AACzE,WAAS,OAAO,QAAQ,6BAA6B,CAAC,GAAG,KAAK,QAAQ;AACpE,UAAM,UAAU,WAAW,GAAG;AAC9B,UAAM,UAAU,WAAW,GAAG;AAC9B,WAAO,aAAa,OAAO,UAAU,OAAO;AAAA,EAC9C,CAAC;AACD,WAAS,OAAO,QAAQ,uBAAuB,CAAC,GAAG,OAAO,SAAS;AACjE,UAAM,WAAW,WAAW,IAAI;AAChC,WAAO,YAAY,QAAQ,sCAAsC,KAAK;AAAA,EACxE,CAAC;AACD,WAAS,OAAO,QAAQ,OAAO,QAAQ;AACvC,SAAO;AACT;AAEA,SAAS,kBAAkB,UAAkB,QAA0B;AACrE,SAAO,SAAS,QAAQ,qBAAqB,CAAC,GAAG,SAAS;AACxD,UAAM,QAAQ,OAAO,KAAK,cAAc,WAAW,KAAK,KAAK,CAAC,CAAC,eAAe,IAAI;AAClF,WAAO,GAAG,gBAAgB,GAAG,KAAK;AAAA,EACpC,CAAC;AACH;AAEA,SAAS,kBAAkB,MAAc,QAA0B;AACjE,SAAO,KAAK,QAAQ,kCAAkC,CAAC,GAAG,aAAa,OAAO,OAAO,QAAQ,CAAC,KAAK,EAAE;AACvG;AAEO,SAAS,qBAAqB,UAA0B;AAC7D,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,QAAM,aAAuB,CAAC;AAC9B,QAAM,cAAc,kBAAkB,UAAU,UAAU;AAC1D,QAAM,aAAa,YAAY,QAAQ,SAAS,IAAI;AAEpD,QAAM,oBAAoB,WACvB,QAAQ,iBAAiB,QAAQ,EACjC,QAAQ,+BAA+B,QAAQ;AAClD,QAAM,SAAS,kBACZ,MAAM,QAAQ,EACd,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,OAAO;AAEjB,QAAM,aAAa,OAAO,IAAI,CAAC,UAAU;AACvC,UAAM,eAAe,MAAM,MAAM,mBAAmB;AACpD,QAAI,cAAc;AAChB,YAAM,QAAQ,aAAa,CAAC,EAAE;AAC9B,YAAM,UAAU,aAAa,aAAa,CAAC,CAAC;AAC5C,aAAO,KAAK,KAAK,IAAI,OAAO,MAAM,KAAK;AAAA,IACzC;AAGA,UAAM,aAAa,MAAM,MAAM,4BAA4B;AAC3D,QAAI,YAAY;AACd,YAAM,UAAU,WAAW,WAAW,CAAC,CAAC;AACxC,YAAM,UAAU,WAAW,WAAW,CAAC,CAAC;AACxC,aAAO,aAAa,OAAO,UAAU,OAAO;AAAA,IAC9C;AAEA,WAAO,MAAM,aAAa,KAAK,CAAC;AAAA,EAClC,CAAC;AAED,QAAM,OAAO,WAAW,KAAK,IAAI;AACjC,SAAO,kBAAkB,MAAM,UAAU;AAC3C;;;AC9EA,OAAO,YAAY;AAsBnB,SAAS,aAAa,MAAe,MAAmC;AACtE,QAAM,UAAU,IAAI,QAAQ,MAAM,OAAO;AACzC,UAAQ,IAAI,gBAAgB,kBAAkB;AAC9C,SAAO,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG;AAAA,IACxC,GAAG;AAAA,IACH;AAAA,EACF,CAAC;AACH;AAEA,SAAS,mBAAmB,WAAyC;AACnE,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,EACT;AACA,QAAM,UAAU,UAAU,KAAK;AAC/B,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,QAAQ,WAAW,SAAS,IAAI,QAAQ,MAAM,CAAC,IAAI;AACzE,MAAI,CAAC,eAAe;AAClB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,WAAO,OAAO,KAAK,eAAe,KAAK;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,uBAAuB,MAA8C;AACnF,QAAM,EAAE,SAAS,WAAW,OAAO,IAAI;AACvC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,iDAAiD;AAAA,EACnE;AACA,QAAM,oBAAoB,mBAAmB,SAAS;AACtD,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,OAAO,YAAY,WAAW,OAAO,KAAK,OAAO,IAAI;AACxE,QAAM,WAAW,OAAO,WAAW,UAAU,MAAM,EAAE,OAAO,UAAU,EAAE,OAAO;AAE/E,MAAI,kBAAkB,WAAW,SAAS,QAAQ;AAChD,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,gBAAgB,mBAAmB,QAAQ;AAC3D;AAEA,SAAS,aAAa,SAA8C;AAClE,QAAM,QAAQ,oBAAI,IAAY,CAAC,gBAAgB,eAAe,OAAO,CAAC;AACtE,MAAI,QAAQ,UAAU;AACpB,UAAM,IAAI,SAAS,QAAQ,QAAQ,EAAE;AAAA,EACvC;AACA,SAAO,MAAM,KAAK,KAAK;AACzB;AAEA,SAAS,YAAY,SAA8C;AACjE,QAAM,OAAO,oBAAI,IAAY;AAC7B,MAAI,QAAQ,eAAe;AACzB,SAAK,IAAI,YAAY,QAAQ,aAAa,UAAU;AACpD,SAAK,IAAI,YAAY,QAAQ,aAAa,QAAQ;AAClD,QAAI,QAAQ,UAAU;AACpB,WAAK,IAAI,YAAY,QAAQ,aAAa,SAAS,QAAQ,QAAQ,EAAE;AAAA,IACvE;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,OAAO,QAAwC;AACtD,MAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AAClC,WAAO,CAAC;AAAA,EACV;AACA,SAAO,MAAM;AAAA,IACX,IAAI;AAAA,MACF,OACG,OAAO,CAAC,UAAU,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,CAAC,EACtE,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC;AAAA,IAChC;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,MAAgC;AAC1D,QAAM,QAAQ,KAAK,YAAY;AAC/B,MAAI,MAAM,SAAS,MAAM,KAAK,MAAM,SAAS,MAAM,GAAG;AACpD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,6BACd,SACyC;AACzC,MAAI,CAAC,QAAQ,QAAQ;AACnB,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AAEA,QAAM,gBAAgB,KAAK,IAAI,GAAG,QAAQ,sBAAsB,GAAG,IAAI;AACvE,QAAM,cAAc,QAAQ,mBAAmB;AAC/C,QAAM,aAAa,QAAQ,kBAAkB;AAE7C,SAAO,eAAe,0BAA0B,SAAqC;AACnF,UAAM,YAAY,QAAQ,QAAQ,IAAI,sBAAsB;AAC5D,UAAM,aAAa,KAAK,IAAI;AAE5B,UAAM,UAAU,MAAM,QAAQ,KAAK;AACnC,UAAM,UAAU,uBAAuB;AAAA,MACrC;AAAA,MACA;AAAA,MACA,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAED,QAAI,CAAC,SAAS;AACZ,aAAO,aAAa,EAAE,OAAO,4BAA4B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7E;AAEA,QAAI;AACJ,QAAI;AACF,gBAAU,KAAK,MAAM,OAAO;AAAA,IAC9B,QAAQ;AACN,aAAO,aAAa,EAAE,OAAO,uBAAuB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACxE;AAEA,QAAI,CAAC,QAAQ,iBAAiB,OAAO,QAAQ,kBAAkB,UAAU;AACvE,aAAO,aAAa,EAAE,OAAO,4BAA4B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7E;AAEA,QAAI,CAAC,QAAQ,MAAM,OAAO,QAAQ,OAAO,UAAU;AACjD,aAAO,aAAa,EAAE,OAAO,wBAAwB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACzE;AAEA,UAAM,YAAY,KAAK,MAAM,QAAQ,EAAE;AACvC,QAAI,OAAO,MAAM,SAAS,GAAG;AAC3B,aAAO,aAAa,EAAE,OAAO,oBAAoB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACrE;AAEA,QAAI,KAAK,IAAI,aAAa,SAAS,IAAI,eAAe;AACpD,aAAO,aAAa,EAAE,OAAO,4CAA4C,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7F;AAEA,UAAM,QAAQ,OAAO,YAAY,OAAO,CAAC;AACzC,UAAM,OAAO,OAAO,WAAW,OAAO,CAAC;AAEvC,QAAI;AACF,UAAI,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAC9C,cAAM,QAAQ;AAAA,UACZ,MAAM,IAAI,CAAC,SAAS,QAAQ,eAAgB,MAAM,mBAAmB,IAAI,CAAC,CAAC;AAAA,QAC7E;AAAA,MACF;AAEA,UAAI,QAAQ,iBAAiB,KAAK,SAAS,GAAG;AAC5C,cAAM,QAAQ,IAAI,KAAK,IAAI,CAAC,QAAQ,QAAQ,cAAe,GAAG,CAAC,CAAC;AAAA,MAClE;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,EAAE,OAAO,8BAA8B,SAAU,MAAgB,QAAQ;AAAA,QACzE,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAEA,WAAO,aAAa;AAAA,MAClB,IAAI;AAAA,MACJ,OAAO,QAAQ,SAAS;AAAA,MACxB,aAAa;AAAA,QACX;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACvKO,SAAS,kBAAkB,MAA8B;AAC9D,QAAM,QAAQ,KAAK,KAAK,SAAS,KAAK;AACtC,QAAM,cAAc,KAAK,KAAK,eAAe,KAAK;AAClD,QAAM,WAAW,KAAK,KAAK;AAC3B,QAAM,YAAY,KAAK,UAAU;AACjC,QAAM,aAAa,KAAK,UAAU;AAElC,QAAM,WAAyB;AAAA,IAC7B;AAAA,IACA;AAAA,EACF;AAEA,MAAI,YAAY,SAAS,SAAS,GAAG;AACnC,aAAS,WAAW;AAAA,EACtB;AAEA,MAAI,WAAW;AACb,aAAS,aAAa,EAAE,UAAU;AAAA,EACpC;AAEA,WAAS,YAAY;AAAA,IACnB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,eAAe,KAAK;AAAA,IACpB,cAAc,KAAK;AAAA,EACrB;AAEA,MAAI,YAAY;AACd,aAAS,UAAU,SAAS,CAAC,EAAE,KAAK,WAAW,CAAC;AAAA,EAClD;AAEA,WAAS,UAAU;AAAA,IACjB,MAAM,aAAa,wBAAwB;AAAA,IAC3C;AAAA,IACA;AAAA,EACF;AAEA,MAAI,YAAY;AACd,aAAS,QAAQ,SAAS,CAAC,UAAU;AAAA,EACvC;AAEA,SAAO;AACT;;;ACjDA,IAAI,YAAsC;AAE1C,SAAS,WAAW,MAAsB;AACxC,QAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,0CAA0C,IAAI,EAAE;AAAA,EAClE;AACA,SAAO;AACT;AAEO,SAAS,wBAA2C;AACzD,MAAI,WAAW;AACb,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,QAAQ,IAAI,oBAAoB;AAC/C,QAAM,SAAS,WAAW,kBAAkB;AAC5C,QAAM,gBAAgB,WAAW,yBAAyB;AAC1D,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,UACJ,QAAQ,IAAI,YAAY,QAAQ,IAAI,wBAAwB;AAC9D,QAAM,mBAAmB,QAAQ,IAAI;AACrC,QAAM,iBAAiB,QAAQ,IAAI;AACnC,QAAM,iBACJ,QAAQ,IAAI,+BAA+B;AAE7C,QAAM,SAAS,qBAAqB;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,cAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,MACJ,OAAO,YAAY,aAAa;AAAA,MAChC,MAAM,CAAC,SAAiB,YAAY,aAAa,SAAS,IAAI;AAAA,MAC9D,SAAS,YAAY,aAAa;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;","names":["normalizeSiteUrl"]}
1
+ {"version":3,"sources":["../src/auth.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/sitemap.ts","../src/robots.ts","../src/render.ts","../src/revalidate.ts","../src/metadata.ts","../src/env.ts"],"sourcesContent":["import { AuthMode } from \"./types\";\n\nexport function buildAuthHeaders(apiKey: string, authMode: AuthMode = \"bearer\"): Record<string, string> {\n if (authMode === \"x-api-key\") {\n return { \"x-api-key\": apiKey };\n }\n return { Authorization: `Bearer ${apiKey}` };\n}\n","export class BlogAutoError extends Error {\n public readonly causeError?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = new.target.name;\n this.causeError = options?.cause;\n }\n}\n\nexport class ConfigError extends BlogAutoError {}\n\nexport interface ApiErrorDetails {\n status: number;\n code?: string;\n details?: unknown;\n}\n\nexport class ApiError extends BlogAutoError {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, info: ApiErrorDetails, options?: { cause?: unknown }) {\n super(message, options);\n this.status = info.status;\n this.code = info.code;\n this.details = info.details;\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, info?: Partial<ApiErrorDetails>) {\n super(message, { status: info?.status ?? 404, code: info?.code, details: info?.details });\n }\n}\n","import { ApiError, ConfigError } from \"./errors\";\nimport { AuthMode, BlogAutoClientConfig, InternalClientConfig } from \"./types\";\n\nexport const DEFAULT_TIMEOUT_MS = 10_000;\n\nexport function normalizeApiUrl(apiUrl: string): string {\n if (!apiUrl) {\n throw new ConfigError(\"apiUrl is required\");\n }\n\n return apiUrl.replace(/\\/$/, \"\");\n}\n\nexport function resolveClientConfig(config: BlogAutoClientConfig): InternalClientConfig {\n if (!config) {\n throw new ConfigError(\"Client configuration is required\");\n }\n\n const apiKey = config.apiKey?.trim();\n if (!apiKey) {\n throw new ConfigError(\"apiKey is required to authenticate with BlogAuto\");\n }\n\n if (!config.workspaceId && !config.workspaceSlug) {\n throw new ConfigError(\"Provide either workspaceId or workspaceSlug\");\n }\n\n const authMode: AuthMode = config.authMode ?? \"bearer\";\n\n return {\n apiKey,\n apiUrl: normalizeApiUrl(config.apiUrl),\n workspaceId: config.workspaceId,\n workspaceSlug: config.workspaceSlug,\n authMode,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n headers: { ...(config.headers ?? {}) },\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n };\n}\n\nexport function buildQuery(params: Record<string, string | number | undefined | null>): string {\n const query = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n query.set(key, String(value));\n });\n const qs = query.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T> {\n if (!timeoutMs) {\n return promise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new ApiError(`Request timed out after ${timeoutMs}ms`, {\n status: 408,\n }),\n );\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: Array<Record<string, string> | undefined>\n): Record<string, string> {\n return headerObjects.reduce<Record<string, string>>((acc, headers) => {\n if (!headers) {\n return acc;\n }\n Object.entries(headers).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n acc[key.toLowerCase()] = value;\n });\n return acc;\n }, {});\n}\n","import { buildAuthHeaders } from \"./auth\";\nimport { ApiError, BlogAutoError, ConfigError } from \"./errors\";\nimport { buildQuery, mergeHeaders, resolveClientConfig, withTimeout } from \"./utils\";\nimport type {\n BlogAutoClientConfig,\n BlogPost,\n FetchRequestOptions,\n PaginatedList,\n PostsResponse,\n} from \"./types\";\n\ninterface RequestOptions {\n path: string;\n method?: string;\n query?: Record<string, string | number | undefined | null>;\n body?: unknown;\n allowNotFound?: boolean;\n headers?: Record<string, string>;\n cache?: RequestCache;\n next?: FetchRequestOptions[\"next\"];\n}\n\nexport interface BlogAutoClient {\n getPosts(params?: { limit?: number; cursor?: string } & FetchRequestOptions): Promise<PostsResponse>;\n getPostBySlug(slug: string, options?: FetchRequestOptions): Promise<BlogPost | null>;\n getSitemapEntries(): Promise<Array<{ slug: string; updatedAt: string }>>;\n}\n\nexport function createBlogAutoClient(config: BlogAutoClientConfig): BlogAutoClient {\n const resolved = resolveClientConfig(config);\n const fetchImpl = resolved.fetch;\n const debug =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.BLOGAUTO_DEBUG === \"true\";\n const debugLog = (...args: unknown[]) => {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\"[blogauto]\", ...args);\n }\n };\n\n function ensureWorkspaceSlug(): string {\n if (!resolved.workspaceSlug) {\n throw new ConfigError(\"workspaceSlug is required to call the BlogAuto public API\");\n }\n return resolved.workspaceSlug;\n }\n\n function buildUrl(path: string, query?: Record<string, string | number | undefined | null>): string {\n const qs = buildQuery(query ?? {});\n return `${resolved.apiUrl}${path}${qs}`;\n }\n\n function unwrapSuccessPayload<T>(payload: unknown): T {\n if (payload && typeof payload === \"object\") {\n const maybePayload = payload as { success?: boolean; data?: T; error?: { message?: string } };\n if (\"success\" in maybePayload) {\n if (maybePayload.success === false) {\n throw new ApiError(\n maybePayload.error?.message ?? \"BlogAuto request failed\",\n { status: 500, details: maybePayload },\n );\n }\n if (maybePayload.success && \"data\" in maybePayload) {\n return maybePayload.data as T;\n }\n }\n }\n return payload as T;\n }\n\n async function request<T>(opts: RequestOptions): Promise<T> {\n const method = opts.method ?? \"GET\";\n const url = buildUrl(opts.path, opts.query);\n\n const authHeaders = buildAuthHeaders(resolved.apiKey, resolved.authMode);\n const baseHeaders = mergeHeaders(resolved.headers, authHeaders, opts.headers);\n\n const init: RequestInit = {\n method,\n headers: baseHeaders,\n };\n\n if (opts.body) {\n init.body = typeof opts.body === \"string\" ? opts.body : JSON.stringify(opts.body);\n init.headers = {\n ...baseHeaders,\n \"content-type\": baseHeaders[\"content-type\"] ?? \"application/json\",\n };\n }\n\n if (opts.cache !== undefined) {\n init.cache = opts.cache;\n }\n\n if (opts.next) {\n (init as RequestInit & { next?: FetchRequestOptions[\"next\"] }).next = opts.next;\n }\n\n const startedAt = Date.now();\n try {\n const response = await withTimeout(fetchImpl(url, init), resolved.timeoutMs);\n debugLog(\"response\", {\n method,\n url,\n status: response.status,\n durationMs: Date.now() - startedAt,\n });\n if (opts.allowNotFound && response.status === 404) {\n return null as T;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n const payload = isJson ? await response.json().catch(() => undefined) : await response.text();\n\n if (!response.ok) {\n if (response.status === 404 && opts.allowNotFound) {\n return null as T;\n }\n\n const errorBody = payload as any;\n const message =\n errorBody?.error?.message ?? errorBody?.message ?? `Request failed with status ${response.status}`;\n throw new ApiError(message, {\n status: response.status,\n code: errorBody?.error?.code ?? errorBody?.code,\n details: errorBody?.error?.details ?? errorBody,\n });\n }\n\n if (isJson) {\n return unwrapSuccessPayload<T>(payload);\n }\n\n return (payload as T) ?? (undefined as T);\n } catch (error) {\n debugLog(\"request failed\", {\n method,\n url,\n durationMs: Date.now() - startedAt,\n error: error instanceof Error ? error.message : error,\n });\n if (error instanceof BlogAutoError) {\n throw error;\n }\n const causeMessage =\n error instanceof Error ? error.message : typeof error === \"string\" ? error : undefined;\n const message = causeMessage\n ? `Network request to BlogAuto failed: ${causeMessage}`\n : \"Network request to BlogAuto failed\";\n throw new ApiError(\n message,\n {\n status: 0,\n details: { url, method },\n },\n { cause: error },\n );\n }\n }\n\n async function fetchBlogPage(\n limit: number,\n page: number,\n cacheOptions?: FetchRequestOptions,\n ): Promise<PaginatedList<BlogPost>> {\n const workspaceSlug = ensureWorkspaceSlug();\n debugLog(\"fetch posts page\", { workspaceSlug, limit, page });\n return request<PaginatedList<BlogPost>>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs`,\n query: { limit, page },\n cache: cacheOptions?.cache,\n next: cacheOptions?.next,\n });\n }\n\n return {\n async getPosts(params) {\n const limit = params?.limit ?? 20;\n const cursorPage = params?.cursor ? Number(params.cursor) : undefined;\n const page = Number.isFinite(cursorPage) && cursorPage! >= 1 ? cursorPage! : 1;\n const data = await fetchBlogPage(limit, page, params);\n return {\n posts: data.items,\n nextCursor: data.pagination.hasMore ? String(data.pagination.page + 1) : undefined,\n };\n },\n async getPostBySlug(slug: string, options?: FetchRequestOptions) {\n if (!slug) {\n throw new ApiError(\"slug is required\", { status: 400 });\n }\n const workspaceSlug = ensureWorkspaceSlug();\n const post = await request<{ post: BlogPost } | null>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs/${encodeURIComponent(slug)}`,\n allowNotFound: true,\n cache: options?.cache,\n next: options?.next,\n });\n if (post === null) {\n return null;\n }\n return post.post;\n },\n async getSitemapEntries() {\n const entries: Array<{ slug: string; updatedAt: string }> = [];\n const limit = 100;\n let page = 1;\n\n while (true) {\n const pageData = await fetchBlogPage(limit, page);\n pageData.items.forEach((post) => {\n entries.push({ slug: post.slug, updatedAt: post.updatedAt });\n });\n\n if (!pageData.pagination.hasMore) {\n break;\n }\n\n page = pageData.pagination.page + 1;\n }\n\n return entries;\n },\n };\n}\n","import { BuildSitemapOptions, MetadataRouteSitemap, MetadataRouteSitemapEntry } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizeRoutePrefix(routePrefix?: string): string {\n if (!routePrefix || routePrefix === \"/\") {\n return \"\";\n }\n const withSlash = routePrefix.startsWith(\"/\") ? routePrefix : `/${routePrefix}`;\n return withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash;\n}\n\nfunction normalizeSlug(slug: string): string {\n return slug.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function buildSitemap(opts: BuildSitemapOptions): MetadataRouteSitemap {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const prefix = normalizeRoutePrefix(opts.routePrefix ?? \"/blog\");\n\n const entries: MetadataRouteSitemapEntry[] = opts.entries.map((entry) => {\n const slug = normalizeSlug(entry.slug);\n const hasSlug = slug.length > 0;\n const slugFragment = hasSlug ? `/${slug}` : \"\";\n const path = prefix ? `${prefix}${slugFragment}` : hasSlug ? `/${slug}` : \"/\";\n return {\n url: `${siteUrl}${path}`,\n lastModified: entry.updatedAt,\n };\n });\n\n return entries;\n}\n","import { BuildRobotsOptions, MetadataRouteRobots } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n if (!path) {\n return \"/sitemap.xml\";\n }\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n return path;\n}\n\nexport function buildRobots(opts: BuildRobotsOptions): MetadataRouteRobots {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const sitemapPath = normalizePath(opts.sitemapPath ?? \"/sitemap.xml\");\n const sitemapUrl = `${siteUrl}${sitemapPath}`;\n\n return {\n rules: [{ userAgent: \"*\", allow: \"/\" }],\n sitemap: sitemapUrl,\n };\n}\n","const CODE_BLOCK_TOKEN = \"__BLOGAUTO_CODE_BLOCK_\";\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\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(/__BLOGAUTO_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 crypto from \"crypto\";\nimport type { BlogAutoRevalidatePayload, RevalidatePathFn, RevalidateTagFn } from \"./types\";\n\nexport interface VerifyWebhookSignatureOptions {\n rawBody: string | Buffer;\n signature: string | null;\n secret: string;\n}\n\nexport interface CreateRevalidateRouteHandlerOptions {\n secret: string;\n allowedSkewSeconds?: number;\n revalidatePath?: RevalidatePathFn;\n revalidateTag?: RevalidateTagFn;\n revalidatePaths?: (payload: BlogAutoRevalidatePayload) => string[];\n revalidateTags?: (payload: BlogAutoRevalidatePayload) => string[];\n}\n\ninterface JsonResponseInit extends ResponseInit {\n status?: number;\n}\n\nfunction jsonResponse(body: unknown, init?: JsonResponseInit): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"content-type\", \"application/json\");\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeSignature(signature: string | null): Buffer | null {\n if (!signature) {\n return null;\n }\n const trimmed = signature.trim();\n if (!trimmed) {\n return null;\n }\n\n const withoutPrefix = trimmed.startsWith(\"sha256=\") ? trimmed.slice(7) : trimmed;\n if (!withoutPrefix) {\n return null;\n }\n\n try {\n return Buffer.from(withoutPrefix, \"hex\");\n } catch {\n return null;\n }\n}\n\nexport function verifyWebhookSignature(opts: VerifyWebhookSignatureOptions): boolean {\n const { rawBody, signature, secret } = opts;\n if (!secret) {\n throw new Error(\"Secret is required to verify webhook signatures\");\n }\n const providedSignature = normalizeSignature(signature);\n if (!providedSignature) {\n return false;\n }\n\n const bodyBuffer = typeof rawBody === \"string\" ? Buffer.from(rawBody) : rawBody;\n const expected = crypto.createHmac(\"sha256\", secret).update(bodyBuffer).digest();\n\n if (providedSignature.length !== expected.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedSignature, expected);\n}\n\nfunction defaultPaths(payload: BlogAutoRevalidatePayload): string[] {\n const paths = new Set<string>([\"/sitemap.xml\", \"/robots.txt\", \"/blog\"]);\n if (payload.postSlug) {\n paths.add(`/blog/${payload.postSlug}`);\n }\n return Array.from(paths);\n}\n\nfunction defaultTags(payload: BlogAutoRevalidatePayload): string[] {\n const tags = new Set<string>();\n if (payload.workspaceSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:sitemap`);\n tags.add(`blogauto:${payload.workspaceSlug}:posts`);\n if (payload.postSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:post:${payload.postSlug}`);\n }\n }\n return Array.from(tags);\n}\n\nfunction dedupe(values: string[] | undefined): string[] {\n if (!values || values.length === 0) {\n return [];\n }\n return Array.from(\n new Set(\n values\n .filter((value) => typeof value === \"string\" && value.trim().length > 0)\n .map((value) => value.trim()),\n ),\n );\n}\n\nfunction determineRouteType(path: string): \"route\" | \"page\" {\n const lower = path.toLowerCase();\n if (lower.endsWith(\".xml\") || lower.endsWith(\".txt\")) {\n return \"route\";\n }\n return \"page\";\n}\n\nexport function createRevalidateRouteHandler(\n options: CreateRevalidateRouteHandlerOptions,\n): (request: Request) => Promise<Response> {\n if (!options.secret) {\n throw new Error(\"secret is required for createRevalidateRouteHandler\");\n }\n\n const allowedSkewMs = Math.max(1, options.allowedSkewSeconds ?? 300) * 1000;\n const pathBuilder = options.revalidatePaths ?? defaultPaths;\n const tagBuilder = options.revalidateTags ?? defaultTags;\n\n return async function blogAutoRevalidateHandler(request: Request): Promise<Response> {\n const signature = request.headers.get(\"x-blogauto-signature\");\n const receivedAt = Date.now();\n\n const rawBody = await request.text();\n const isValid = verifyWebhookSignature({\n rawBody,\n signature,\n secret: options.secret,\n });\n\n if (!isValid) {\n return jsonResponse({ error: \"Invalid webhook signature\" }, { status: 401 });\n }\n\n let payload: BlogAutoRevalidatePayload;\n try {\n payload = JSON.parse(rawBody) as BlogAutoRevalidatePayload;\n } catch {\n return jsonResponse({ error: \"Invalid JSON payload\" }, { status: 400 });\n }\n\n if (!payload.workspaceSlug || typeof payload.workspaceSlug !== \"string\") {\n return jsonResponse({ error: \"workspaceSlug is required\" }, { status: 400 });\n }\n\n if (!payload.ts || typeof payload.ts !== \"string\") {\n return jsonResponse({ error: \"Timestamp is required\" }, { status: 400 });\n }\n\n const payloadTs = Date.parse(payload.ts);\n if (Number.isNaN(payloadTs)) {\n return jsonResponse({ error: \"Invalid timestamp\" }, { status: 400 });\n }\n\n if (Math.abs(receivedAt - payloadTs) > allowedSkewMs) {\n return jsonResponse({ error: \"Webhook timestamp is outside allowed skew\" }, { status: 409 });\n }\n\n const paths = dedupe(pathBuilder(payload));\n const tags = dedupe(tagBuilder(payload));\n\n try {\n if (options.revalidatePath && paths.length > 0) {\n await Promise.all(\n paths.map((path) => options.revalidatePath!(path, determineRouteType(path))),\n );\n }\n\n if (options.revalidateTag && tags.length > 0) {\n await Promise.all(tags.map((tag) => options.revalidateTag!(tag)));\n }\n } catch (error) {\n return jsonResponse(\n { error: \"Failed to revalidate cache\", details: (error as Error).message },\n { status: 500 },\n );\n }\n\n return jsonResponse({\n ok: true,\n event: payload.event ?? \"post.published\",\n revalidated: {\n paths,\n tags,\n },\n });\n };\n}\n","import type { BlogPost } from \"./types\";\n\nexport interface NextMetadata {\n title?: string;\n description?: string;\n keywords?: string[];\n alternates?: {\n canonical?: string;\n };\n openGraph?: {\n type?: string;\n title?: string;\n description?: string;\n images?: Array<{ url: string }>;\n publishedTime?: string;\n modifiedTime?: string;\n };\n twitter?: {\n card?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n}\n\nexport function buildNextMetadata(post: BlogPost): NextMetadata {\n const title = post.seo?.title ?? post.title;\n const description = post.seo?.description ?? post.excerpt;\n const keywords = post.seo?.keywords;\n const canonical = post.metadata?.canonicalUrl;\n const ogImageUrl = post.metadata?.ogImageUrl;\n\n const metadata: NextMetadata = {\n title,\n description,\n };\n\n if (keywords && keywords.length > 0) {\n metadata.keywords = keywords;\n }\n\n if (canonical) {\n metadata.alternates = { canonical };\n }\n\n metadata.openGraph = {\n type: \"article\",\n title,\n description,\n publishedTime: post.publishedAt,\n modifiedTime: post.updatedAt,\n };\n\n if (ogImageUrl) {\n metadata.openGraph.images = [{ url: ogImageUrl }];\n }\n\n metadata.twitter = {\n card: ogImageUrl ? \"summary_large_image\" : \"summary\",\n title,\n description,\n };\n\n if (ogImageUrl) {\n metadata.twitter.images = [ogImageUrl];\n }\n\n return metadata;\n}\n","import { createBlogAutoClient, type BlogAutoClient } from \"./client\";\n\nexport interface BlogAutoEnvConfig {\n client: BlogAutoClient;\n workspaceSlug: string;\n workspaceId?: string;\n siteUrl: string;\n revalidateSecret?: string;\n apiUrl: string;\n apiKey: string;\n tags: {\n posts: string;\n post: (slug: string) => string;\n sitemap: string;\n };\n}\n\nlet _instance: BlogAutoEnvConfig | null = null;\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\nexport function createBlogAutoFromEnv(): BlogAutoEnvConfig {\n if (_instance) {\n return _instance;\n }\n\n const apiUrl = process.env.BLOGAUTO_API_URL ?? \"https://api.blogauto.io\";\n const apiKey = requireEnv(\"BLOGAUTO_API_KEY\");\n const workspaceSlug = requireEnv(\"BLOGAUTO_WORKSPACE_SLUG\");\n const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;\n const siteUrl =\n process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? \"http://localhost:3000\";\n const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;\n\n const client = createBlogAutoClient({\n apiUrl,\n apiKey,\n workspaceSlug,\n workspaceId,\n });\n\n _instance = {\n client,\n workspaceSlug,\n workspaceId,\n siteUrl,\n revalidateSecret,\n apiUrl,\n apiKey,\n tags: {\n posts: `blogauto:${workspaceSlug}:posts`,\n post: (slug: string) => `blogauto:${workspaceSlug}:post:${slug}`,\n sitemap: `blogauto:${workspaceSlug}:sitemap`,\n },\n };\n\n return _instance;\n}\n"],"mappings":"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","names":["normalizeSiteUrl"]}
package/dist/next.cjs CHANGED
@@ -30,7 +30,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/next/index.ts
31
31
  var next_exports = {};
32
32
  __export(next_exports, {
33
- createEnvAnalyticsHandler: () => createEnvAnalyticsHandler,
34
33
  createEnvRevalidateHandler: () => createEnvRevalidateHandler,
35
34
  fetchBlogPost: () => fetchBlogPost,
36
35
  fetchBlogPosts: () => fetchBlogPosts,
@@ -331,8 +330,6 @@ function createBlogAutoFromEnv() {
331
330
  const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;
332
331
  const siteUrl = process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000";
333
332
  const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;
334
- const analyticsToken = process.env.NEXT_PUBLIC_ANALYTICS_TOKEN;
335
- const analyticsProxy = process.env.NEXT_PUBLIC_ANALYTICS_PROXY ?? "/api/blogauto/analytics";
336
333
  const client = createBlogAutoClient({
337
334
  apiUrl,
338
335
  apiKey,
@@ -345,8 +342,6 @@ function createBlogAutoFromEnv() {
345
342
  workspaceId,
346
343
  siteUrl,
347
344
  revalidateSecret,
348
- analyticsToken,
349
- analyticsProxy,
350
345
  apiUrl,
351
346
  apiKey,
352
347
  tags: {
@@ -661,47 +656,8 @@ function createEnvRevalidateHandler() {
661
656
  return handler(request);
662
657
  };
663
658
  }
664
- function createEnvAnalyticsHandler() {
665
- return async (request) => {
666
- const { analyticsToken, apiUrl, apiKey, workspaceId, workspaceSlug } = createBlogAutoFromEnv();
667
- if (!analyticsToken) {
668
- return new Response(
669
- JSON.stringify({ error: "Analytics proxy disabled" }),
670
- { status: 503, headers: { "content-type": "application/json" } }
671
- );
672
- }
673
- const provided = request.headers.get("x-api-key");
674
- if (provided !== analyticsToken) {
675
- return new Response(
676
- JSON.stringify({ error: "Unauthorized" }),
677
- { status: 401, headers: { "content-type": "application/json" } }
678
- );
679
- }
680
- const payload = await request.json();
681
- const envelope = {
682
- ...payload,
683
- workspaceId: workspaceId ?? payload.workspaceId,
684
- workspaceSlug: workspaceSlug ?? payload.workspaceSlug
685
- };
686
- const response = await fetch(`${apiUrl}/v1/analytics/ingest`, {
687
- method: "POST",
688
- headers: {
689
- "content-type": "application/json",
690
- ...buildAuthHeaders(apiKey, "bearer")
691
- },
692
- body: JSON.stringify(envelope)
693
- });
694
- const text = await response.text();
695
- const contentType = response.headers.get("content-type") ?? "application/json";
696
- return new Response(text || "{}", {
697
- status: response.status,
698
- headers: { "content-type": contentType }
699
- });
700
- };
701
- }
702
659
  // Annotate the CommonJS export names for ESM import in node:
703
660
  0 && (module.exports = {
704
- createEnvAnalyticsHandler,
705
661
  createEnvRevalidateHandler,
706
662
  fetchBlogPost,
707
663
  fetchBlogPosts,
package/dist/next.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/next/index.ts","../src/auth.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/env.ts","../src/metadata.ts","../src/sitemap.ts","../src/robots.ts","../src/next/helpers.ts","../src/revalidate.ts","../src/next/route-handlers.ts"],"sourcesContent":["export {\n fetchBlogPost,\n fetchBlogPosts,\n generatePostMetadata,\n generateBlogSitemap,\n generateBlogRobots,\n type FetchBlogPostsOptions,\n} from \"./helpers\";\n\nexport {\n createEnvRevalidateHandler,\n createEnvAnalyticsHandler,\n} from \"./route-handlers\";\n","import { AuthMode } from \"./types\";\n\nexport function buildAuthHeaders(apiKey: string, authMode: AuthMode = \"bearer\"): Record<string, string> {\n if (authMode === \"x-api-key\") {\n return { \"x-api-key\": apiKey };\n }\n return { Authorization: `Bearer ${apiKey}` };\n}\n","export class BlogAutoError extends Error {\n public readonly causeError?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = new.target.name;\n this.causeError = options?.cause;\n }\n}\n\nexport class ConfigError extends BlogAutoError {}\n\nexport interface ApiErrorDetails {\n status: number;\n code?: string;\n details?: unknown;\n}\n\nexport class ApiError extends BlogAutoError {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, info: ApiErrorDetails, options?: { cause?: unknown }) {\n super(message, options);\n this.status = info.status;\n this.code = info.code;\n this.details = info.details;\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, info?: Partial<ApiErrorDetails>) {\n super(message, { status: info?.status ?? 404, code: info?.code, details: info?.details });\n }\n}\n","import { ApiError, ConfigError } from \"./errors\";\nimport { AuthMode, BlogAutoClientConfig, InternalClientConfig } from \"./types\";\n\nexport const DEFAULT_TIMEOUT_MS = 10_000;\n\nexport function normalizeApiUrl(apiUrl: string): string {\n if (!apiUrl) {\n throw new ConfigError(\"apiUrl is required\");\n }\n\n return apiUrl.replace(/\\/$/, \"\");\n}\n\nexport function resolveClientConfig(config: BlogAutoClientConfig): InternalClientConfig {\n if (!config) {\n throw new ConfigError(\"Client configuration is required\");\n }\n\n const apiKey = config.apiKey?.trim();\n if (!apiKey) {\n throw new ConfigError(\"apiKey is required to authenticate with BlogAuto\");\n }\n\n if (!config.workspaceId && !config.workspaceSlug) {\n throw new ConfigError(\"Provide either workspaceId or workspaceSlug\");\n }\n\n const authMode: AuthMode = config.authMode ?? \"bearer\";\n\n return {\n apiKey,\n apiUrl: normalizeApiUrl(config.apiUrl),\n workspaceId: config.workspaceId,\n workspaceSlug: config.workspaceSlug,\n authMode,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n headers: { ...(config.headers ?? {}) },\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n };\n}\n\nexport function buildQuery(params: Record<string, string | number | undefined | null>): string {\n const query = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n query.set(key, String(value));\n });\n const qs = query.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T> {\n if (!timeoutMs) {\n return promise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new ApiError(`Request timed out after ${timeoutMs}ms`, {\n status: 408,\n }),\n );\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: Array<Record<string, string> | undefined>\n): Record<string, string> {\n return headerObjects.reduce<Record<string, string>>((acc, headers) => {\n if (!headers) {\n return acc;\n }\n Object.entries(headers).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n acc[key.toLowerCase()] = value;\n });\n return acc;\n }, {});\n}\n","import { buildAuthHeaders } from \"./auth\";\nimport { ApiError, BlogAutoError, ConfigError } from \"./errors\";\nimport { buildQuery, mergeHeaders, resolveClientConfig, withTimeout } from \"./utils\";\nimport type {\n BlogAutoClientConfig,\n BlogPost,\n FetchRequestOptions,\n PaginatedList,\n PostsResponse,\n} from \"./types\";\n\ninterface RequestOptions {\n path: string;\n method?: string;\n query?: Record<string, string | number | undefined | null>;\n body?: unknown;\n allowNotFound?: boolean;\n headers?: Record<string, string>;\n cache?: RequestCache;\n next?: FetchRequestOptions[\"next\"];\n}\n\nexport interface BlogAutoClient {\n getPosts(params?: { limit?: number; cursor?: string } & FetchRequestOptions): Promise<PostsResponse>;\n getPostBySlug(slug: string, options?: FetchRequestOptions): Promise<BlogPost | null>;\n getSitemapEntries(): Promise<Array<{ slug: string; updatedAt: string }>>;\n}\n\nexport function createBlogAutoClient(config: BlogAutoClientConfig): BlogAutoClient {\n const resolved = resolveClientConfig(config);\n const fetchImpl = resolved.fetch;\n const debug =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.BLOGAUTO_DEBUG === \"true\";\n const debugLog = (...args: unknown[]) => {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\"[blogauto]\", ...args);\n }\n };\n\n function ensureWorkspaceSlug(): string {\n if (!resolved.workspaceSlug) {\n throw new ConfigError(\"workspaceSlug is required to call the BlogAuto public API\");\n }\n return resolved.workspaceSlug;\n }\n\n function buildUrl(path: string, query?: Record<string, string | number | undefined | null>): string {\n const qs = buildQuery(query ?? {});\n return `${resolved.apiUrl}${path}${qs}`;\n }\n\n function unwrapSuccessPayload<T>(payload: unknown): T {\n if (payload && typeof payload === \"object\") {\n const maybePayload = payload as { success?: boolean; data?: T; error?: { message?: string } };\n if (\"success\" in maybePayload) {\n if (maybePayload.success === false) {\n throw new ApiError(\n maybePayload.error?.message ?? \"BlogAuto request failed\",\n { status: 500, details: maybePayload },\n );\n }\n if (maybePayload.success && \"data\" in maybePayload) {\n return maybePayload.data as T;\n }\n }\n }\n return payload as T;\n }\n\n async function request<T>(opts: RequestOptions): Promise<T> {\n const method = opts.method ?? \"GET\";\n const url = buildUrl(opts.path, opts.query);\n\n const authHeaders = buildAuthHeaders(resolved.apiKey, resolved.authMode);\n const baseHeaders = mergeHeaders(resolved.headers, authHeaders, opts.headers);\n\n const init: RequestInit = {\n method,\n headers: baseHeaders,\n };\n\n if (opts.body) {\n init.body = typeof opts.body === \"string\" ? opts.body : JSON.stringify(opts.body);\n init.headers = {\n ...baseHeaders,\n \"content-type\": baseHeaders[\"content-type\"] ?? \"application/json\",\n };\n }\n\n if (opts.cache !== undefined) {\n init.cache = opts.cache;\n }\n\n if (opts.next) {\n (init as RequestInit & { next?: FetchRequestOptions[\"next\"] }).next = opts.next;\n }\n\n const startedAt = Date.now();\n try {\n const response = await withTimeout(fetchImpl(url, init), resolved.timeoutMs);\n debugLog(\"response\", {\n method,\n url,\n status: response.status,\n durationMs: Date.now() - startedAt,\n });\n if (opts.allowNotFound && response.status === 404) {\n return null as T;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n const payload = isJson ? await response.json().catch(() => undefined) : await response.text();\n\n if (!response.ok) {\n if (response.status === 404 && opts.allowNotFound) {\n return null as T;\n }\n\n const errorBody = payload as any;\n const message =\n errorBody?.error?.message ?? errorBody?.message ?? `Request failed with status ${response.status}`;\n throw new ApiError(message, {\n status: response.status,\n code: errorBody?.error?.code ?? errorBody?.code,\n details: errorBody?.error?.details ?? errorBody,\n });\n }\n\n if (isJson) {\n return unwrapSuccessPayload<T>(payload);\n }\n\n return (payload as T) ?? (undefined as T);\n } catch (error) {\n debugLog(\"request failed\", {\n method,\n url,\n durationMs: Date.now() - startedAt,\n error: error instanceof Error ? error.message : error,\n });\n if (error instanceof BlogAutoError) {\n throw error;\n }\n const causeMessage =\n error instanceof Error ? error.message : typeof error === \"string\" ? error : undefined;\n const message = causeMessage\n ? `Network request to BlogAuto failed: ${causeMessage}`\n : \"Network request to BlogAuto failed\";\n throw new ApiError(\n message,\n {\n status: 0,\n details: { url, method },\n },\n { cause: error },\n );\n }\n }\n\n async function fetchBlogPage(\n limit: number,\n page: number,\n cacheOptions?: FetchRequestOptions,\n ): Promise<PaginatedList<BlogPost>> {\n const workspaceSlug = ensureWorkspaceSlug();\n debugLog(\"fetch posts page\", { workspaceSlug, limit, page });\n return request<PaginatedList<BlogPost>>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs`,\n query: { limit, page },\n cache: cacheOptions?.cache,\n next: cacheOptions?.next,\n });\n }\n\n return {\n async getPosts(params) {\n const limit = params?.limit ?? 20;\n const cursorPage = params?.cursor ? Number(params.cursor) : undefined;\n const page = Number.isFinite(cursorPage) && cursorPage! >= 1 ? cursorPage! : 1;\n const data = await fetchBlogPage(limit, page, params);\n return {\n posts: data.items,\n nextCursor: data.pagination.hasMore ? String(data.pagination.page + 1) : undefined,\n };\n },\n async getPostBySlug(slug: string, options?: FetchRequestOptions) {\n if (!slug) {\n throw new ApiError(\"slug is required\", { status: 400 });\n }\n const workspaceSlug = ensureWorkspaceSlug();\n const post = await request<{ post: BlogPost } | null>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs/${encodeURIComponent(slug)}`,\n allowNotFound: true,\n cache: options?.cache,\n next: options?.next,\n });\n if (post === null) {\n return null;\n }\n return post.post;\n },\n async getSitemapEntries() {\n const entries: Array<{ slug: string; updatedAt: string }> = [];\n const limit = 100;\n let page = 1;\n\n while (true) {\n const pageData = await fetchBlogPage(limit, page);\n pageData.items.forEach((post) => {\n entries.push({ slug: post.slug, updatedAt: post.updatedAt });\n });\n\n if (!pageData.pagination.hasMore) {\n break;\n }\n\n page = pageData.pagination.page + 1;\n }\n\n return entries;\n },\n };\n}\n","import { createBlogAutoClient, type BlogAutoClient } from \"./client\";\n\nexport interface BlogAutoEnvConfig {\n client: BlogAutoClient;\n workspaceSlug: string;\n workspaceId?: string;\n siteUrl: string;\n revalidateSecret?: string;\n analyticsToken?: string;\n analyticsProxy: string;\n apiUrl: string;\n apiKey: string;\n tags: {\n posts: string;\n post: (slug: string) => string;\n sitemap: string;\n };\n}\n\nlet _instance: BlogAutoEnvConfig | null = null;\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\nexport function createBlogAutoFromEnv(): BlogAutoEnvConfig {\n if (_instance) {\n return _instance;\n }\n\n const apiUrl = process.env.BLOGAUTO_API_URL ?? \"https://api.blogauto.io\";\n const apiKey = requireEnv(\"BLOGAUTO_API_KEY\");\n const workspaceSlug = requireEnv(\"BLOGAUTO_WORKSPACE_SLUG\");\n const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;\n const siteUrl =\n process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? \"http://localhost:3000\";\n const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;\n const analyticsToken = process.env.NEXT_PUBLIC_ANALYTICS_TOKEN;\n const analyticsProxy =\n process.env.NEXT_PUBLIC_ANALYTICS_PROXY ?? \"/api/blogauto/analytics\";\n\n const client = createBlogAutoClient({\n apiUrl,\n apiKey,\n workspaceSlug,\n workspaceId,\n });\n\n _instance = {\n client,\n workspaceSlug,\n workspaceId,\n siteUrl,\n revalidateSecret,\n analyticsToken,\n analyticsProxy,\n apiUrl,\n apiKey,\n tags: {\n posts: `blogauto:${workspaceSlug}:posts`,\n post: (slug: string) => `blogauto:${workspaceSlug}:post:${slug}`,\n sitemap: `blogauto:${workspaceSlug}:sitemap`,\n },\n };\n\n return _instance;\n}\n","import type { BlogPost } from \"./types\";\n\nexport interface NextMetadata {\n title?: string;\n description?: string;\n keywords?: string[];\n alternates?: {\n canonical?: string;\n };\n openGraph?: {\n type?: string;\n title?: string;\n description?: string;\n images?: Array<{ url: string }>;\n publishedTime?: string;\n modifiedTime?: string;\n };\n twitter?: {\n card?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n}\n\nexport function buildNextMetadata(post: BlogPost): NextMetadata {\n const title = post.seo?.title ?? post.title;\n const description = post.seo?.description ?? post.excerpt;\n const keywords = post.seo?.keywords;\n const canonical = post.metadata?.canonicalUrl;\n const ogImageUrl = post.metadata?.ogImageUrl;\n\n const metadata: NextMetadata = {\n title,\n description,\n };\n\n if (keywords && keywords.length > 0) {\n metadata.keywords = keywords;\n }\n\n if (canonical) {\n metadata.alternates = { canonical };\n }\n\n metadata.openGraph = {\n type: \"article\",\n title,\n description,\n publishedTime: post.publishedAt,\n modifiedTime: post.updatedAt,\n };\n\n if (ogImageUrl) {\n metadata.openGraph.images = [{ url: ogImageUrl }];\n }\n\n metadata.twitter = {\n card: ogImageUrl ? \"summary_large_image\" : \"summary\",\n title,\n description,\n };\n\n if (ogImageUrl) {\n metadata.twitter.images = [ogImageUrl];\n }\n\n return metadata;\n}\n","import { BuildSitemapOptions, MetadataRouteSitemap, MetadataRouteSitemapEntry } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizeRoutePrefix(routePrefix?: string): string {\n if (!routePrefix || routePrefix === \"/\") {\n return \"\";\n }\n const withSlash = routePrefix.startsWith(\"/\") ? routePrefix : `/${routePrefix}`;\n return withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash;\n}\n\nfunction normalizeSlug(slug: string): string {\n return slug.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function buildSitemap(opts: BuildSitemapOptions): MetadataRouteSitemap {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const prefix = normalizeRoutePrefix(opts.routePrefix ?? \"/blog\");\n\n const entries: MetadataRouteSitemapEntry[] = opts.entries.map((entry) => {\n const slug = normalizeSlug(entry.slug);\n const hasSlug = slug.length > 0;\n const slugFragment = hasSlug ? `/${slug}` : \"\";\n const path = prefix ? `${prefix}${slugFragment}` : hasSlug ? `/${slug}` : \"/\";\n return {\n url: `${siteUrl}${path}`,\n lastModified: entry.updatedAt,\n };\n });\n\n return entries;\n}\n","import { BuildRobotsOptions, MetadataRouteRobots } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n if (!path) {\n return \"/sitemap.xml\";\n }\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n return path;\n}\n\nexport function buildRobots(opts: BuildRobotsOptions): MetadataRouteRobots {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const sitemapPath = normalizePath(opts.sitemapPath ?? \"/sitemap.xml\");\n const sitemapUrl = `${siteUrl}${sitemapPath}`;\n\n return {\n rules: [{ userAgent: \"*\", allow: \"/\" }],\n sitemap: sitemapUrl,\n };\n}\n","import { createBlogAutoFromEnv } from \"../env\";\nimport { buildNextMetadata, type NextMetadata } from \"../metadata\";\nimport { buildSitemap } from \"../sitemap\";\nimport { buildRobots } from \"../robots\";\nimport type { BlogPost, PostsResponse, MetadataRouteSitemap, MetadataRouteRobots } from \"../types\";\n\nexport interface FetchBlogPostsOptions {\n limit?: number;\n cursor?: string;\n}\n\nexport async function fetchBlogPosts(options?: FetchBlogPostsOptions): Promise<PostsResponse> {\n const { client, tags } = createBlogAutoFromEnv();\n return client.getPosts({\n limit: options?.limit,\n cursor: options?.cursor,\n next: { tags: [tags.posts] },\n });\n}\n\nexport async function fetchBlogPost(slug: string): Promise<BlogPost> {\n const { client, tags } = createBlogAutoFromEnv();\n const post = await client.getPostBySlug(slug, {\n next: { tags: [tags.post(slug)] },\n });\n\n if (!post) {\n // Dynamic import to avoid pulling next/navigation into non-Next environments\n const nav = await import(/* webpackIgnore: true */ \"next/navigation\" as string) as {\n notFound: () => never;\n };\n nav.notFound();\n // notFound() throws, but TS can't infer `never` through dynamic import\n throw new Error(\"notFound\");\n }\n\n return post;\n}\n\nexport async function generatePostMetadata(slug: string): Promise<NextMetadata> {\n const { client, tags } = createBlogAutoFromEnv();\n const post = await client.getPostBySlug(slug, {\n next: { tags: [tags.post(slug)] },\n });\n\n if (!post) {\n return {};\n }\n\n return buildNextMetadata(post);\n}\n\nexport async function generateBlogSitemap(): Promise<MetadataRouteSitemap> {\n const { client, siteUrl } = createBlogAutoFromEnv();\n const entries = await client.getSitemapEntries();\n return buildSitemap({ siteUrl, routePrefix: \"/blog\", entries });\n}\n\nexport function generateBlogRobots(): MetadataRouteRobots {\n const { siteUrl } = createBlogAutoFromEnv();\n return buildRobots({ siteUrl, sitemapPath: \"/sitemap.xml\" });\n}\n","import crypto from \"crypto\";\nimport type { BlogAutoRevalidatePayload, RevalidatePathFn, RevalidateTagFn } from \"./types\";\n\nexport interface VerifyWebhookSignatureOptions {\n rawBody: string | Buffer;\n signature: string | null;\n secret: string;\n}\n\nexport interface CreateRevalidateRouteHandlerOptions {\n secret: string;\n allowedSkewSeconds?: number;\n revalidatePath?: RevalidatePathFn;\n revalidateTag?: RevalidateTagFn;\n revalidatePaths?: (payload: BlogAutoRevalidatePayload) => string[];\n revalidateTags?: (payload: BlogAutoRevalidatePayload) => string[];\n}\n\ninterface JsonResponseInit extends ResponseInit {\n status?: number;\n}\n\nfunction jsonResponse(body: unknown, init?: JsonResponseInit): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"content-type\", \"application/json\");\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeSignature(signature: string | null): Buffer | null {\n if (!signature) {\n return null;\n }\n const trimmed = signature.trim();\n if (!trimmed) {\n return null;\n }\n\n const withoutPrefix = trimmed.startsWith(\"sha256=\") ? trimmed.slice(7) : trimmed;\n if (!withoutPrefix) {\n return null;\n }\n\n try {\n return Buffer.from(withoutPrefix, \"hex\");\n } catch {\n return null;\n }\n}\n\nexport function verifyWebhookSignature(opts: VerifyWebhookSignatureOptions): boolean {\n const { rawBody, signature, secret } = opts;\n if (!secret) {\n throw new Error(\"Secret is required to verify webhook signatures\");\n }\n const providedSignature = normalizeSignature(signature);\n if (!providedSignature) {\n return false;\n }\n\n const bodyBuffer = typeof rawBody === \"string\" ? Buffer.from(rawBody) : rawBody;\n const expected = crypto.createHmac(\"sha256\", secret).update(bodyBuffer).digest();\n\n if (providedSignature.length !== expected.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedSignature, expected);\n}\n\nfunction defaultPaths(payload: BlogAutoRevalidatePayload): string[] {\n const paths = new Set<string>([\"/sitemap.xml\", \"/robots.txt\", \"/blog\"]);\n if (payload.postSlug) {\n paths.add(`/blog/${payload.postSlug}`);\n }\n return Array.from(paths);\n}\n\nfunction defaultTags(payload: BlogAutoRevalidatePayload): string[] {\n const tags = new Set<string>();\n if (payload.workspaceSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:sitemap`);\n tags.add(`blogauto:${payload.workspaceSlug}:posts`);\n if (payload.postSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:post:${payload.postSlug}`);\n }\n }\n return Array.from(tags);\n}\n\nfunction dedupe(values: string[] | undefined): string[] {\n if (!values || values.length === 0) {\n return [];\n }\n return Array.from(\n new Set(\n values\n .filter((value) => typeof value === \"string\" && value.trim().length > 0)\n .map((value) => value.trim()),\n ),\n );\n}\n\nfunction determineRouteType(path: string): \"route\" | \"page\" {\n const lower = path.toLowerCase();\n if (lower.endsWith(\".xml\") || lower.endsWith(\".txt\")) {\n return \"route\";\n }\n return \"page\";\n}\n\nexport function createRevalidateRouteHandler(\n options: CreateRevalidateRouteHandlerOptions,\n): (request: Request) => Promise<Response> {\n if (!options.secret) {\n throw new Error(\"secret is required for createRevalidateRouteHandler\");\n }\n\n const allowedSkewMs = Math.max(1, options.allowedSkewSeconds ?? 300) * 1000;\n const pathBuilder = options.revalidatePaths ?? defaultPaths;\n const tagBuilder = options.revalidateTags ?? defaultTags;\n\n return async function blogAutoRevalidateHandler(request: Request): Promise<Response> {\n const signature = request.headers.get(\"x-blogauto-signature\");\n const receivedAt = Date.now();\n\n const rawBody = await request.text();\n const isValid = verifyWebhookSignature({\n rawBody,\n signature,\n secret: options.secret,\n });\n\n if (!isValid) {\n return jsonResponse({ error: \"Invalid webhook signature\" }, { status: 401 });\n }\n\n let payload: BlogAutoRevalidatePayload;\n try {\n payload = JSON.parse(rawBody) as BlogAutoRevalidatePayload;\n } catch {\n return jsonResponse({ error: \"Invalid JSON payload\" }, { status: 400 });\n }\n\n if (!payload.workspaceSlug || typeof payload.workspaceSlug !== \"string\") {\n return jsonResponse({ error: \"workspaceSlug is required\" }, { status: 400 });\n }\n\n if (!payload.ts || typeof payload.ts !== \"string\") {\n return jsonResponse({ error: \"Timestamp is required\" }, { status: 400 });\n }\n\n const payloadTs = Date.parse(payload.ts);\n if (Number.isNaN(payloadTs)) {\n return jsonResponse({ error: \"Invalid timestamp\" }, { status: 400 });\n }\n\n if (Math.abs(receivedAt - payloadTs) > allowedSkewMs) {\n return jsonResponse({ error: \"Webhook timestamp is outside allowed skew\" }, { status: 409 });\n }\n\n const paths = dedupe(pathBuilder(payload));\n const tags = dedupe(tagBuilder(payload));\n\n try {\n if (options.revalidatePath && paths.length > 0) {\n await Promise.all(\n paths.map((path) => options.revalidatePath!(path, determineRouteType(path))),\n );\n }\n\n if (options.revalidateTag && tags.length > 0) {\n await Promise.all(tags.map((tag) => options.revalidateTag!(tag)));\n }\n } catch (error) {\n return jsonResponse(\n { error: \"Failed to revalidate cache\", details: (error as Error).message },\n { status: 500 },\n );\n }\n\n return jsonResponse({\n ok: true,\n event: payload.event ?? \"post.published\",\n revalidated: {\n paths,\n tags,\n },\n });\n };\n}\n","import { createBlogAutoFromEnv } from \"../env\";\nimport { createRevalidateRouteHandler } from \"../revalidate\";\nimport { buildAuthHeaders } from \"../auth\";\n\nexport function createEnvRevalidateHandler(): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n // Lazy init so env vars are read at request time, not module load time\n const { revalidateSecret } = createBlogAutoFromEnv();\n\n if (!revalidateSecret) {\n return new Response(\n JSON.stringify({ error: \"Missing BLOGAUTO_REVALIDATE_SECRET\" }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n\n // Dynamic import to avoid pulling next/cache into non-Next environments\n const nextCache = await import(/* webpackIgnore: true */ \"next/cache\" as string) as {\n revalidatePath: (path: string, type?: \"page\" | \"layout\" | \"route\") => void;\n revalidateTag: (tag: string) => void;\n };\n const { revalidatePath, revalidateTag } = nextCache;\n\n const handler = createRevalidateRouteHandler({\n secret: revalidateSecret,\n revalidatePath,\n revalidateTag,\n });\n\n return handler(request);\n };\n}\n\nexport function createEnvAnalyticsHandler(): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n const { analyticsToken, apiUrl, apiKey, workspaceId, workspaceSlug } =\n createBlogAutoFromEnv();\n\n if (!analyticsToken) {\n return new Response(\n JSON.stringify({ error: \"Analytics proxy disabled\" }),\n { status: 503, headers: { \"content-type\": \"application/json\" } },\n );\n }\n\n const provided = request.headers.get(\"x-api-key\");\n if (provided !== analyticsToken) {\n return new Response(\n JSON.stringify({ error: \"Unauthorized\" }),\n { status: 401, headers: { \"content-type\": \"application/json\" } },\n );\n }\n\n const payload = await request.json();\n const envelope = {\n ...payload,\n workspaceId: workspaceId ?? payload.workspaceId,\n workspaceSlug: workspaceSlug ?? payload.workspaceSlug,\n };\n\n const response = await fetch(`${apiUrl}/v1/analytics/ingest`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...buildAuthHeaders(apiKey, \"bearer\"),\n },\n body: JSON.stringify(envelope),\n });\n\n const text = await response.text();\n const contentType = response.headers.get(\"content-type\") ?? \"application/json\";\n\n return new Response(text || \"{}\", {\n status: response.status,\n headers: { \"content-type\": contentType },\n });\n };\n}\n"],"mappings":"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","names":["normalizeSiteUrl","crypto"]}
1
+ {"version":3,"sources":["../src/next/index.ts","../src/auth.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/env.ts","../src/metadata.ts","../src/sitemap.ts","../src/robots.ts","../src/next/helpers.ts","../src/revalidate.ts","../src/next/route-handlers.ts"],"sourcesContent":["export {\n fetchBlogPost,\n fetchBlogPosts,\n generatePostMetadata,\n generateBlogSitemap,\n generateBlogRobots,\n type FetchBlogPostsOptions,\n} from \"./helpers\";\n\nexport {\n createEnvRevalidateHandler,\n} from \"./route-handlers\";\n","import { AuthMode } from \"./types\";\n\nexport function buildAuthHeaders(apiKey: string, authMode: AuthMode = \"bearer\"): Record<string, string> {\n if (authMode === \"x-api-key\") {\n return { \"x-api-key\": apiKey };\n }\n return { Authorization: `Bearer ${apiKey}` };\n}\n","export class BlogAutoError extends Error {\n public readonly causeError?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = new.target.name;\n this.causeError = options?.cause;\n }\n}\n\nexport class ConfigError extends BlogAutoError {}\n\nexport interface ApiErrorDetails {\n status: number;\n code?: string;\n details?: unknown;\n}\n\nexport class ApiError extends BlogAutoError {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, info: ApiErrorDetails, options?: { cause?: unknown }) {\n super(message, options);\n this.status = info.status;\n this.code = info.code;\n this.details = info.details;\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, info?: Partial<ApiErrorDetails>) {\n super(message, { status: info?.status ?? 404, code: info?.code, details: info?.details });\n }\n}\n","import { ApiError, ConfigError } from \"./errors\";\nimport { AuthMode, BlogAutoClientConfig, InternalClientConfig } from \"./types\";\n\nexport const DEFAULT_TIMEOUT_MS = 10_000;\n\nexport function normalizeApiUrl(apiUrl: string): string {\n if (!apiUrl) {\n throw new ConfigError(\"apiUrl is required\");\n }\n\n return apiUrl.replace(/\\/$/, \"\");\n}\n\nexport function resolveClientConfig(config: BlogAutoClientConfig): InternalClientConfig {\n if (!config) {\n throw new ConfigError(\"Client configuration is required\");\n }\n\n const apiKey = config.apiKey?.trim();\n if (!apiKey) {\n throw new ConfigError(\"apiKey is required to authenticate with BlogAuto\");\n }\n\n if (!config.workspaceId && !config.workspaceSlug) {\n throw new ConfigError(\"Provide either workspaceId or workspaceSlug\");\n }\n\n const authMode: AuthMode = config.authMode ?? \"bearer\";\n\n return {\n apiKey,\n apiUrl: normalizeApiUrl(config.apiUrl),\n workspaceId: config.workspaceId,\n workspaceSlug: config.workspaceSlug,\n authMode,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n headers: { ...(config.headers ?? {}) },\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n };\n}\n\nexport function buildQuery(params: Record<string, string | number | undefined | null>): string {\n const query = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n query.set(key, String(value));\n });\n const qs = query.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T> {\n if (!timeoutMs) {\n return promise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new ApiError(`Request timed out after ${timeoutMs}ms`, {\n status: 408,\n }),\n );\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: Array<Record<string, string> | undefined>\n): Record<string, string> {\n return headerObjects.reduce<Record<string, string>>((acc, headers) => {\n if (!headers) {\n return acc;\n }\n Object.entries(headers).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n acc[key.toLowerCase()] = value;\n });\n return acc;\n }, {});\n}\n","import { buildAuthHeaders } from \"./auth\";\nimport { ApiError, BlogAutoError, ConfigError } from \"./errors\";\nimport { buildQuery, mergeHeaders, resolveClientConfig, withTimeout } from \"./utils\";\nimport type {\n BlogAutoClientConfig,\n BlogPost,\n FetchRequestOptions,\n PaginatedList,\n PostsResponse,\n} from \"./types\";\n\ninterface RequestOptions {\n path: string;\n method?: string;\n query?: Record<string, string | number | undefined | null>;\n body?: unknown;\n allowNotFound?: boolean;\n headers?: Record<string, string>;\n cache?: RequestCache;\n next?: FetchRequestOptions[\"next\"];\n}\n\nexport interface BlogAutoClient {\n getPosts(params?: { limit?: number; cursor?: string } & FetchRequestOptions): Promise<PostsResponse>;\n getPostBySlug(slug: string, options?: FetchRequestOptions): Promise<BlogPost | null>;\n getSitemapEntries(): Promise<Array<{ slug: string; updatedAt: string }>>;\n}\n\nexport function createBlogAutoClient(config: BlogAutoClientConfig): BlogAutoClient {\n const resolved = resolveClientConfig(config);\n const fetchImpl = resolved.fetch;\n const debug =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.BLOGAUTO_DEBUG === \"true\";\n const debugLog = (...args: unknown[]) => {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\"[blogauto]\", ...args);\n }\n };\n\n function ensureWorkspaceSlug(): string {\n if (!resolved.workspaceSlug) {\n throw new ConfigError(\"workspaceSlug is required to call the BlogAuto public API\");\n }\n return resolved.workspaceSlug;\n }\n\n function buildUrl(path: string, query?: Record<string, string | number | undefined | null>): string {\n const qs = buildQuery(query ?? {});\n return `${resolved.apiUrl}${path}${qs}`;\n }\n\n function unwrapSuccessPayload<T>(payload: unknown): T {\n if (payload && typeof payload === \"object\") {\n const maybePayload = payload as { success?: boolean; data?: T; error?: { message?: string } };\n if (\"success\" in maybePayload) {\n if (maybePayload.success === false) {\n throw new ApiError(\n maybePayload.error?.message ?? \"BlogAuto request failed\",\n { status: 500, details: maybePayload },\n );\n }\n if (maybePayload.success && \"data\" in maybePayload) {\n return maybePayload.data as T;\n }\n }\n }\n return payload as T;\n }\n\n async function request<T>(opts: RequestOptions): Promise<T> {\n const method = opts.method ?? \"GET\";\n const url = buildUrl(opts.path, opts.query);\n\n const authHeaders = buildAuthHeaders(resolved.apiKey, resolved.authMode);\n const baseHeaders = mergeHeaders(resolved.headers, authHeaders, opts.headers);\n\n const init: RequestInit = {\n method,\n headers: baseHeaders,\n };\n\n if (opts.body) {\n init.body = typeof opts.body === \"string\" ? opts.body : JSON.stringify(opts.body);\n init.headers = {\n ...baseHeaders,\n \"content-type\": baseHeaders[\"content-type\"] ?? \"application/json\",\n };\n }\n\n if (opts.cache !== undefined) {\n init.cache = opts.cache;\n }\n\n if (opts.next) {\n (init as RequestInit & { next?: FetchRequestOptions[\"next\"] }).next = opts.next;\n }\n\n const startedAt = Date.now();\n try {\n const response = await withTimeout(fetchImpl(url, init), resolved.timeoutMs);\n debugLog(\"response\", {\n method,\n url,\n status: response.status,\n durationMs: Date.now() - startedAt,\n });\n if (opts.allowNotFound && response.status === 404) {\n return null as T;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n const payload = isJson ? await response.json().catch(() => undefined) : await response.text();\n\n if (!response.ok) {\n if (response.status === 404 && opts.allowNotFound) {\n return null as T;\n }\n\n const errorBody = payload as any;\n const message =\n errorBody?.error?.message ?? errorBody?.message ?? `Request failed with status ${response.status}`;\n throw new ApiError(message, {\n status: response.status,\n code: errorBody?.error?.code ?? errorBody?.code,\n details: errorBody?.error?.details ?? errorBody,\n });\n }\n\n if (isJson) {\n return unwrapSuccessPayload<T>(payload);\n }\n\n return (payload as T) ?? (undefined as T);\n } catch (error) {\n debugLog(\"request failed\", {\n method,\n url,\n durationMs: Date.now() - startedAt,\n error: error instanceof Error ? error.message : error,\n });\n if (error instanceof BlogAutoError) {\n throw error;\n }\n const causeMessage =\n error instanceof Error ? error.message : typeof error === \"string\" ? error : undefined;\n const message = causeMessage\n ? `Network request to BlogAuto failed: ${causeMessage}`\n : \"Network request to BlogAuto failed\";\n throw new ApiError(\n message,\n {\n status: 0,\n details: { url, method },\n },\n { cause: error },\n );\n }\n }\n\n async function fetchBlogPage(\n limit: number,\n page: number,\n cacheOptions?: FetchRequestOptions,\n ): Promise<PaginatedList<BlogPost>> {\n const workspaceSlug = ensureWorkspaceSlug();\n debugLog(\"fetch posts page\", { workspaceSlug, limit, page });\n return request<PaginatedList<BlogPost>>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs`,\n query: { limit, page },\n cache: cacheOptions?.cache,\n next: cacheOptions?.next,\n });\n }\n\n return {\n async getPosts(params) {\n const limit = params?.limit ?? 20;\n const cursorPage = params?.cursor ? Number(params.cursor) : undefined;\n const page = Number.isFinite(cursorPage) && cursorPage! >= 1 ? cursorPage! : 1;\n const data = await fetchBlogPage(limit, page, params);\n return {\n posts: data.items,\n nextCursor: data.pagination.hasMore ? String(data.pagination.page + 1) : undefined,\n };\n },\n async getPostBySlug(slug: string, options?: FetchRequestOptions) {\n if (!slug) {\n throw new ApiError(\"slug is required\", { status: 400 });\n }\n const workspaceSlug = ensureWorkspaceSlug();\n const post = await request<{ post: BlogPost } | null>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs/${encodeURIComponent(slug)}`,\n allowNotFound: true,\n cache: options?.cache,\n next: options?.next,\n });\n if (post === null) {\n return null;\n }\n return post.post;\n },\n async getSitemapEntries() {\n const entries: Array<{ slug: string; updatedAt: string }> = [];\n const limit = 100;\n let page = 1;\n\n while (true) {\n const pageData = await fetchBlogPage(limit, page);\n pageData.items.forEach((post) => {\n entries.push({ slug: post.slug, updatedAt: post.updatedAt });\n });\n\n if (!pageData.pagination.hasMore) {\n break;\n }\n\n page = pageData.pagination.page + 1;\n }\n\n return entries;\n },\n };\n}\n","import { createBlogAutoClient, type BlogAutoClient } from \"./client\";\n\nexport interface BlogAutoEnvConfig {\n client: BlogAutoClient;\n workspaceSlug: string;\n workspaceId?: string;\n siteUrl: string;\n revalidateSecret?: string;\n apiUrl: string;\n apiKey: string;\n tags: {\n posts: string;\n post: (slug: string) => string;\n sitemap: string;\n };\n}\n\nlet _instance: BlogAutoEnvConfig | null = null;\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\nexport function createBlogAutoFromEnv(): BlogAutoEnvConfig {\n if (_instance) {\n return _instance;\n }\n\n const apiUrl = process.env.BLOGAUTO_API_URL ?? \"https://api.blogauto.io\";\n const apiKey = requireEnv(\"BLOGAUTO_API_KEY\");\n const workspaceSlug = requireEnv(\"BLOGAUTO_WORKSPACE_SLUG\");\n const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;\n const siteUrl =\n process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? \"http://localhost:3000\";\n const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;\n\n const client = createBlogAutoClient({\n apiUrl,\n apiKey,\n workspaceSlug,\n workspaceId,\n });\n\n _instance = {\n client,\n workspaceSlug,\n workspaceId,\n siteUrl,\n revalidateSecret,\n apiUrl,\n apiKey,\n tags: {\n posts: `blogauto:${workspaceSlug}:posts`,\n post: (slug: string) => `blogauto:${workspaceSlug}:post:${slug}`,\n sitemap: `blogauto:${workspaceSlug}:sitemap`,\n },\n };\n\n return _instance;\n}\n","import type { BlogPost } from \"./types\";\n\nexport interface NextMetadata {\n title?: string;\n description?: string;\n keywords?: string[];\n alternates?: {\n canonical?: string;\n };\n openGraph?: {\n type?: string;\n title?: string;\n description?: string;\n images?: Array<{ url: string }>;\n publishedTime?: string;\n modifiedTime?: string;\n };\n twitter?: {\n card?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n}\n\nexport function buildNextMetadata(post: BlogPost): NextMetadata {\n const title = post.seo?.title ?? post.title;\n const description = post.seo?.description ?? post.excerpt;\n const keywords = post.seo?.keywords;\n const canonical = post.metadata?.canonicalUrl;\n const ogImageUrl = post.metadata?.ogImageUrl;\n\n const metadata: NextMetadata = {\n title,\n description,\n };\n\n if (keywords && keywords.length > 0) {\n metadata.keywords = keywords;\n }\n\n if (canonical) {\n metadata.alternates = { canonical };\n }\n\n metadata.openGraph = {\n type: \"article\",\n title,\n description,\n publishedTime: post.publishedAt,\n modifiedTime: post.updatedAt,\n };\n\n if (ogImageUrl) {\n metadata.openGraph.images = [{ url: ogImageUrl }];\n }\n\n metadata.twitter = {\n card: ogImageUrl ? \"summary_large_image\" : \"summary\",\n title,\n description,\n };\n\n if (ogImageUrl) {\n metadata.twitter.images = [ogImageUrl];\n }\n\n return metadata;\n}\n","import { BuildSitemapOptions, MetadataRouteSitemap, MetadataRouteSitemapEntry } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizeRoutePrefix(routePrefix?: string): string {\n if (!routePrefix || routePrefix === \"/\") {\n return \"\";\n }\n const withSlash = routePrefix.startsWith(\"/\") ? routePrefix : `/${routePrefix}`;\n return withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash;\n}\n\nfunction normalizeSlug(slug: string): string {\n return slug.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function buildSitemap(opts: BuildSitemapOptions): MetadataRouteSitemap {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const prefix = normalizeRoutePrefix(opts.routePrefix ?? \"/blog\");\n\n const entries: MetadataRouteSitemapEntry[] = opts.entries.map((entry) => {\n const slug = normalizeSlug(entry.slug);\n const hasSlug = slug.length > 0;\n const slugFragment = hasSlug ? `/${slug}` : \"\";\n const path = prefix ? `${prefix}${slugFragment}` : hasSlug ? `/${slug}` : \"/\";\n return {\n url: `${siteUrl}${path}`,\n lastModified: entry.updatedAt,\n };\n });\n\n return entries;\n}\n","import { BuildRobotsOptions, MetadataRouteRobots } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n if (!path) {\n return \"/sitemap.xml\";\n }\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n return path;\n}\n\nexport function buildRobots(opts: BuildRobotsOptions): MetadataRouteRobots {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const sitemapPath = normalizePath(opts.sitemapPath ?? \"/sitemap.xml\");\n const sitemapUrl = `${siteUrl}${sitemapPath}`;\n\n return {\n rules: [{ userAgent: \"*\", allow: \"/\" }],\n sitemap: sitemapUrl,\n };\n}\n","import { createBlogAutoFromEnv } from \"../env\";\nimport { buildNextMetadata, type NextMetadata } from \"../metadata\";\nimport { buildSitemap } from \"../sitemap\";\nimport { buildRobots } from \"../robots\";\nimport type { BlogPost, PostsResponse, MetadataRouteSitemap, MetadataRouteRobots } from \"../types\";\n\nexport interface FetchBlogPostsOptions {\n limit?: number;\n cursor?: string;\n}\n\nexport async function fetchBlogPosts(options?: FetchBlogPostsOptions): Promise<PostsResponse> {\n const { client, tags } = createBlogAutoFromEnv();\n return client.getPosts({\n limit: options?.limit,\n cursor: options?.cursor,\n next: { tags: [tags.posts] },\n });\n}\n\nexport async function fetchBlogPost(slug: string): Promise<BlogPost> {\n const { client, tags } = createBlogAutoFromEnv();\n const post = await client.getPostBySlug(slug, {\n next: { tags: [tags.post(slug)] },\n });\n\n if (!post) {\n // Dynamic import to avoid pulling next/navigation into non-Next environments\n const nav = await import(/* webpackIgnore: true */ \"next/navigation\" as string) as {\n notFound: () => never;\n };\n nav.notFound();\n // notFound() throws, but TS can't infer `never` through dynamic import\n throw new Error(\"notFound\");\n }\n\n return post;\n}\n\nexport async function generatePostMetadata(slug: string): Promise<NextMetadata> {\n const { client, tags } = createBlogAutoFromEnv();\n const post = await client.getPostBySlug(slug, {\n next: { tags: [tags.post(slug)] },\n });\n\n if (!post) {\n return {};\n }\n\n return buildNextMetadata(post);\n}\n\nexport async function generateBlogSitemap(): Promise<MetadataRouteSitemap> {\n const { client, siteUrl } = createBlogAutoFromEnv();\n const entries = await client.getSitemapEntries();\n return buildSitemap({ siteUrl, routePrefix: \"/blog\", entries });\n}\n\nexport function generateBlogRobots(): MetadataRouteRobots {\n const { siteUrl } = createBlogAutoFromEnv();\n return buildRobots({ siteUrl, sitemapPath: \"/sitemap.xml\" });\n}\n","import crypto from \"crypto\";\nimport type { BlogAutoRevalidatePayload, RevalidatePathFn, RevalidateTagFn } from \"./types\";\n\nexport interface VerifyWebhookSignatureOptions {\n rawBody: string | Buffer;\n signature: string | null;\n secret: string;\n}\n\nexport interface CreateRevalidateRouteHandlerOptions {\n secret: string;\n allowedSkewSeconds?: number;\n revalidatePath?: RevalidatePathFn;\n revalidateTag?: RevalidateTagFn;\n revalidatePaths?: (payload: BlogAutoRevalidatePayload) => string[];\n revalidateTags?: (payload: BlogAutoRevalidatePayload) => string[];\n}\n\ninterface JsonResponseInit extends ResponseInit {\n status?: number;\n}\n\nfunction jsonResponse(body: unknown, init?: JsonResponseInit): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"content-type\", \"application/json\");\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeSignature(signature: string | null): Buffer | null {\n if (!signature) {\n return null;\n }\n const trimmed = signature.trim();\n if (!trimmed) {\n return null;\n }\n\n const withoutPrefix = trimmed.startsWith(\"sha256=\") ? trimmed.slice(7) : trimmed;\n if (!withoutPrefix) {\n return null;\n }\n\n try {\n return Buffer.from(withoutPrefix, \"hex\");\n } catch {\n return null;\n }\n}\n\nexport function verifyWebhookSignature(opts: VerifyWebhookSignatureOptions): boolean {\n const { rawBody, signature, secret } = opts;\n if (!secret) {\n throw new Error(\"Secret is required to verify webhook signatures\");\n }\n const providedSignature = normalizeSignature(signature);\n if (!providedSignature) {\n return false;\n }\n\n const bodyBuffer = typeof rawBody === \"string\" ? Buffer.from(rawBody) : rawBody;\n const expected = crypto.createHmac(\"sha256\", secret).update(bodyBuffer).digest();\n\n if (providedSignature.length !== expected.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedSignature, expected);\n}\n\nfunction defaultPaths(payload: BlogAutoRevalidatePayload): string[] {\n const paths = new Set<string>([\"/sitemap.xml\", \"/robots.txt\", \"/blog\"]);\n if (payload.postSlug) {\n paths.add(`/blog/${payload.postSlug}`);\n }\n return Array.from(paths);\n}\n\nfunction defaultTags(payload: BlogAutoRevalidatePayload): string[] {\n const tags = new Set<string>();\n if (payload.workspaceSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:sitemap`);\n tags.add(`blogauto:${payload.workspaceSlug}:posts`);\n if (payload.postSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:post:${payload.postSlug}`);\n }\n }\n return Array.from(tags);\n}\n\nfunction dedupe(values: string[] | undefined): string[] {\n if (!values || values.length === 0) {\n return [];\n }\n return Array.from(\n new Set(\n values\n .filter((value) => typeof value === \"string\" && value.trim().length > 0)\n .map((value) => value.trim()),\n ),\n );\n}\n\nfunction determineRouteType(path: string): \"route\" | \"page\" {\n const lower = path.toLowerCase();\n if (lower.endsWith(\".xml\") || lower.endsWith(\".txt\")) {\n return \"route\";\n }\n return \"page\";\n}\n\nexport function createRevalidateRouteHandler(\n options: CreateRevalidateRouteHandlerOptions,\n): (request: Request) => Promise<Response> {\n if (!options.secret) {\n throw new Error(\"secret is required for createRevalidateRouteHandler\");\n }\n\n const allowedSkewMs = Math.max(1, options.allowedSkewSeconds ?? 300) * 1000;\n const pathBuilder = options.revalidatePaths ?? defaultPaths;\n const tagBuilder = options.revalidateTags ?? defaultTags;\n\n return async function blogAutoRevalidateHandler(request: Request): Promise<Response> {\n const signature = request.headers.get(\"x-blogauto-signature\");\n const receivedAt = Date.now();\n\n const rawBody = await request.text();\n const isValid = verifyWebhookSignature({\n rawBody,\n signature,\n secret: options.secret,\n });\n\n if (!isValid) {\n return jsonResponse({ error: \"Invalid webhook signature\" }, { status: 401 });\n }\n\n let payload: BlogAutoRevalidatePayload;\n try {\n payload = JSON.parse(rawBody) as BlogAutoRevalidatePayload;\n } catch {\n return jsonResponse({ error: \"Invalid JSON payload\" }, { status: 400 });\n }\n\n if (!payload.workspaceSlug || typeof payload.workspaceSlug !== \"string\") {\n return jsonResponse({ error: \"workspaceSlug is required\" }, { status: 400 });\n }\n\n if (!payload.ts || typeof payload.ts !== \"string\") {\n return jsonResponse({ error: \"Timestamp is required\" }, { status: 400 });\n }\n\n const payloadTs = Date.parse(payload.ts);\n if (Number.isNaN(payloadTs)) {\n return jsonResponse({ error: \"Invalid timestamp\" }, { status: 400 });\n }\n\n if (Math.abs(receivedAt - payloadTs) > allowedSkewMs) {\n return jsonResponse({ error: \"Webhook timestamp is outside allowed skew\" }, { status: 409 });\n }\n\n const paths = dedupe(pathBuilder(payload));\n const tags = dedupe(tagBuilder(payload));\n\n try {\n if (options.revalidatePath && paths.length > 0) {\n await Promise.all(\n paths.map((path) => options.revalidatePath!(path, determineRouteType(path))),\n );\n }\n\n if (options.revalidateTag && tags.length > 0) {\n await Promise.all(tags.map((tag) => options.revalidateTag!(tag)));\n }\n } catch (error) {\n return jsonResponse(\n { error: \"Failed to revalidate cache\", details: (error as Error).message },\n { status: 500 },\n );\n }\n\n return jsonResponse({\n ok: true,\n event: payload.event ?? \"post.published\",\n revalidated: {\n paths,\n tags,\n },\n });\n };\n}\n","import { createBlogAutoFromEnv } from \"../env\";\nimport { createRevalidateRouteHandler } from \"../revalidate\";\n\nexport function createEnvRevalidateHandler(): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n // Lazy init so env vars are read at request time, not module load time\n const { revalidateSecret } = createBlogAutoFromEnv();\n\n if (!revalidateSecret) {\n return new Response(\n JSON.stringify({ error: \"Missing BLOGAUTO_REVALIDATE_SECRET\" }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n\n // Dynamic import to avoid pulling next/cache into non-Next environments\n const nextCache = await import(/* webpackIgnore: true */ \"next/cache\" as string) as {\n revalidatePath: (path: string, type?: \"page\" | \"layout\" | \"route\") => void;\n revalidateTag: (tag: string) => void;\n };\n const { revalidatePath, revalidateTag } = nextCache;\n\n const handler = createRevalidateRouteHandler({\n secret: revalidateSecret,\n revalidatePath,\n revalidateTag,\n });\n\n return handler(request);\n };\n}\n"],"mappings":"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","names":["normalizeSiteUrl","crypto"]}
package/dist/next.d.cts CHANGED
@@ -12,6 +12,5 @@ declare function generateBlogSitemap(): Promise<MetadataRouteSitemap>;
12
12
  declare function generateBlogRobots(): MetadataRouteRobots;
13
13
 
14
14
  declare function createEnvRevalidateHandler(): (request: Request) => Promise<Response>;
15
- declare function createEnvAnalyticsHandler(): (request: Request) => Promise<Response>;
16
15
 
17
- export { type FetchBlogPostsOptions, createEnvAnalyticsHandler, createEnvRevalidateHandler, fetchBlogPost, fetchBlogPosts, generateBlogRobots, generateBlogSitemap, generatePostMetadata };
16
+ export { type FetchBlogPostsOptions, createEnvRevalidateHandler, fetchBlogPost, fetchBlogPosts, generateBlogRobots, generateBlogSitemap, generatePostMetadata };
package/dist/next.d.ts CHANGED
@@ -12,6 +12,5 @@ declare function generateBlogSitemap(): Promise<MetadataRouteSitemap>;
12
12
  declare function generateBlogRobots(): MetadataRouteRobots;
13
13
 
14
14
  declare function createEnvRevalidateHandler(): (request: Request) => Promise<Response>;
15
- declare function createEnvAnalyticsHandler(): (request: Request) => Promise<Response>;
16
15
 
17
- export { type FetchBlogPostsOptions, createEnvAnalyticsHandler, createEnvRevalidateHandler, fetchBlogPost, fetchBlogPosts, generateBlogRobots, generateBlogSitemap, generatePostMetadata };
16
+ export { type FetchBlogPostsOptions, createEnvRevalidateHandler, fetchBlogPost, fetchBlogPosts, generateBlogRobots, generateBlogSitemap, generatePostMetadata };
package/dist/next.js CHANGED
@@ -289,8 +289,6 @@ function createBlogAutoFromEnv() {
289
289
  const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;
290
290
  const siteUrl = process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000";
291
291
  const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;
292
- const analyticsToken = process.env.NEXT_PUBLIC_ANALYTICS_TOKEN;
293
- const analyticsProxy = process.env.NEXT_PUBLIC_ANALYTICS_PROXY ?? "/api/blogauto/analytics";
294
292
  const client = createBlogAutoClient({
295
293
  apiUrl,
296
294
  apiKey,
@@ -303,8 +301,6 @@ function createBlogAutoFromEnv() {
303
301
  workspaceId,
304
302
  siteUrl,
305
303
  revalidateSecret,
306
- analyticsToken,
307
- analyticsProxy,
308
304
  apiUrl,
309
305
  apiKey,
310
306
  tags: {
@@ -619,46 +615,7 @@ function createEnvRevalidateHandler() {
619
615
  return handler(request);
620
616
  };
621
617
  }
622
- function createEnvAnalyticsHandler() {
623
- return async (request) => {
624
- const { analyticsToken, apiUrl, apiKey, workspaceId, workspaceSlug } = createBlogAutoFromEnv();
625
- if (!analyticsToken) {
626
- return new Response(
627
- JSON.stringify({ error: "Analytics proxy disabled" }),
628
- { status: 503, headers: { "content-type": "application/json" } }
629
- );
630
- }
631
- const provided = request.headers.get("x-api-key");
632
- if (provided !== analyticsToken) {
633
- return new Response(
634
- JSON.stringify({ error: "Unauthorized" }),
635
- { status: 401, headers: { "content-type": "application/json" } }
636
- );
637
- }
638
- const payload = await request.json();
639
- const envelope = {
640
- ...payload,
641
- workspaceId: workspaceId ?? payload.workspaceId,
642
- workspaceSlug: workspaceSlug ?? payload.workspaceSlug
643
- };
644
- const response = await fetch(`${apiUrl}/v1/analytics/ingest`, {
645
- method: "POST",
646
- headers: {
647
- "content-type": "application/json",
648
- ...buildAuthHeaders(apiKey, "bearer")
649
- },
650
- body: JSON.stringify(envelope)
651
- });
652
- const text = await response.text();
653
- const contentType = response.headers.get("content-type") ?? "application/json";
654
- return new Response(text || "{}", {
655
- status: response.status,
656
- headers: { "content-type": contentType }
657
- });
658
- };
659
- }
660
618
  export {
661
- createEnvAnalyticsHandler,
662
619
  createEnvRevalidateHandler,
663
620
  fetchBlogPost,
664
621
  fetchBlogPosts,
package/dist/next.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/env.ts","../src/metadata.ts","../src/sitemap.ts","../src/robots.ts","../src/next/helpers.ts","../src/revalidate.ts","../src/next/route-handlers.ts"],"sourcesContent":["import { AuthMode } from \"./types\";\n\nexport function buildAuthHeaders(apiKey: string, authMode: AuthMode = \"bearer\"): Record<string, string> {\n if (authMode === \"x-api-key\") {\n return { \"x-api-key\": apiKey };\n }\n return { Authorization: `Bearer ${apiKey}` };\n}\n","export class BlogAutoError extends Error {\n public readonly causeError?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = new.target.name;\n this.causeError = options?.cause;\n }\n}\n\nexport class ConfigError extends BlogAutoError {}\n\nexport interface ApiErrorDetails {\n status: number;\n code?: string;\n details?: unknown;\n}\n\nexport class ApiError extends BlogAutoError {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, info: ApiErrorDetails, options?: { cause?: unknown }) {\n super(message, options);\n this.status = info.status;\n this.code = info.code;\n this.details = info.details;\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, info?: Partial<ApiErrorDetails>) {\n super(message, { status: info?.status ?? 404, code: info?.code, details: info?.details });\n }\n}\n","import { ApiError, ConfigError } from \"./errors\";\nimport { AuthMode, BlogAutoClientConfig, InternalClientConfig } from \"./types\";\n\nexport const DEFAULT_TIMEOUT_MS = 10_000;\n\nexport function normalizeApiUrl(apiUrl: string): string {\n if (!apiUrl) {\n throw new ConfigError(\"apiUrl is required\");\n }\n\n return apiUrl.replace(/\\/$/, \"\");\n}\n\nexport function resolveClientConfig(config: BlogAutoClientConfig): InternalClientConfig {\n if (!config) {\n throw new ConfigError(\"Client configuration is required\");\n }\n\n const apiKey = config.apiKey?.trim();\n if (!apiKey) {\n throw new ConfigError(\"apiKey is required to authenticate with BlogAuto\");\n }\n\n if (!config.workspaceId && !config.workspaceSlug) {\n throw new ConfigError(\"Provide either workspaceId or workspaceSlug\");\n }\n\n const authMode: AuthMode = config.authMode ?? \"bearer\";\n\n return {\n apiKey,\n apiUrl: normalizeApiUrl(config.apiUrl),\n workspaceId: config.workspaceId,\n workspaceSlug: config.workspaceSlug,\n authMode,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n headers: { ...(config.headers ?? {}) },\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n };\n}\n\nexport function buildQuery(params: Record<string, string | number | undefined | null>): string {\n const query = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n query.set(key, String(value));\n });\n const qs = query.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T> {\n if (!timeoutMs) {\n return promise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new ApiError(`Request timed out after ${timeoutMs}ms`, {\n status: 408,\n }),\n );\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: Array<Record<string, string> | undefined>\n): Record<string, string> {\n return headerObjects.reduce<Record<string, string>>((acc, headers) => {\n if (!headers) {\n return acc;\n }\n Object.entries(headers).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n acc[key.toLowerCase()] = value;\n });\n return acc;\n }, {});\n}\n","import { buildAuthHeaders } from \"./auth\";\nimport { ApiError, BlogAutoError, ConfigError } from \"./errors\";\nimport { buildQuery, mergeHeaders, resolveClientConfig, withTimeout } from \"./utils\";\nimport type {\n BlogAutoClientConfig,\n BlogPost,\n FetchRequestOptions,\n PaginatedList,\n PostsResponse,\n} from \"./types\";\n\ninterface RequestOptions {\n path: string;\n method?: string;\n query?: Record<string, string | number | undefined | null>;\n body?: unknown;\n allowNotFound?: boolean;\n headers?: Record<string, string>;\n cache?: RequestCache;\n next?: FetchRequestOptions[\"next\"];\n}\n\nexport interface BlogAutoClient {\n getPosts(params?: { limit?: number; cursor?: string } & FetchRequestOptions): Promise<PostsResponse>;\n getPostBySlug(slug: string, options?: FetchRequestOptions): Promise<BlogPost | null>;\n getSitemapEntries(): Promise<Array<{ slug: string; updatedAt: string }>>;\n}\n\nexport function createBlogAutoClient(config: BlogAutoClientConfig): BlogAutoClient {\n const resolved = resolveClientConfig(config);\n const fetchImpl = resolved.fetch;\n const debug =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.BLOGAUTO_DEBUG === \"true\";\n const debugLog = (...args: unknown[]) => {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\"[blogauto]\", ...args);\n }\n };\n\n function ensureWorkspaceSlug(): string {\n if (!resolved.workspaceSlug) {\n throw new ConfigError(\"workspaceSlug is required to call the BlogAuto public API\");\n }\n return resolved.workspaceSlug;\n }\n\n function buildUrl(path: string, query?: Record<string, string | number | undefined | null>): string {\n const qs = buildQuery(query ?? {});\n return `${resolved.apiUrl}${path}${qs}`;\n }\n\n function unwrapSuccessPayload<T>(payload: unknown): T {\n if (payload && typeof payload === \"object\") {\n const maybePayload = payload as { success?: boolean; data?: T; error?: { message?: string } };\n if (\"success\" in maybePayload) {\n if (maybePayload.success === false) {\n throw new ApiError(\n maybePayload.error?.message ?? \"BlogAuto request failed\",\n { status: 500, details: maybePayload },\n );\n }\n if (maybePayload.success && \"data\" in maybePayload) {\n return maybePayload.data as T;\n }\n }\n }\n return payload as T;\n }\n\n async function request<T>(opts: RequestOptions): Promise<T> {\n const method = opts.method ?? \"GET\";\n const url = buildUrl(opts.path, opts.query);\n\n const authHeaders = buildAuthHeaders(resolved.apiKey, resolved.authMode);\n const baseHeaders = mergeHeaders(resolved.headers, authHeaders, opts.headers);\n\n const init: RequestInit = {\n method,\n headers: baseHeaders,\n };\n\n if (opts.body) {\n init.body = typeof opts.body === \"string\" ? opts.body : JSON.stringify(opts.body);\n init.headers = {\n ...baseHeaders,\n \"content-type\": baseHeaders[\"content-type\"] ?? \"application/json\",\n };\n }\n\n if (opts.cache !== undefined) {\n init.cache = opts.cache;\n }\n\n if (opts.next) {\n (init as RequestInit & { next?: FetchRequestOptions[\"next\"] }).next = opts.next;\n }\n\n const startedAt = Date.now();\n try {\n const response = await withTimeout(fetchImpl(url, init), resolved.timeoutMs);\n debugLog(\"response\", {\n method,\n url,\n status: response.status,\n durationMs: Date.now() - startedAt,\n });\n if (opts.allowNotFound && response.status === 404) {\n return null as T;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n const payload = isJson ? await response.json().catch(() => undefined) : await response.text();\n\n if (!response.ok) {\n if (response.status === 404 && opts.allowNotFound) {\n return null as T;\n }\n\n const errorBody = payload as any;\n const message =\n errorBody?.error?.message ?? errorBody?.message ?? `Request failed with status ${response.status}`;\n throw new ApiError(message, {\n status: response.status,\n code: errorBody?.error?.code ?? errorBody?.code,\n details: errorBody?.error?.details ?? errorBody,\n });\n }\n\n if (isJson) {\n return unwrapSuccessPayload<T>(payload);\n }\n\n return (payload as T) ?? (undefined as T);\n } catch (error) {\n debugLog(\"request failed\", {\n method,\n url,\n durationMs: Date.now() - startedAt,\n error: error instanceof Error ? error.message : error,\n });\n if (error instanceof BlogAutoError) {\n throw error;\n }\n const causeMessage =\n error instanceof Error ? error.message : typeof error === \"string\" ? error : undefined;\n const message = causeMessage\n ? `Network request to BlogAuto failed: ${causeMessage}`\n : \"Network request to BlogAuto failed\";\n throw new ApiError(\n message,\n {\n status: 0,\n details: { url, method },\n },\n { cause: error },\n );\n }\n }\n\n async function fetchBlogPage(\n limit: number,\n page: number,\n cacheOptions?: FetchRequestOptions,\n ): Promise<PaginatedList<BlogPost>> {\n const workspaceSlug = ensureWorkspaceSlug();\n debugLog(\"fetch posts page\", { workspaceSlug, limit, page });\n return request<PaginatedList<BlogPost>>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs`,\n query: { limit, page },\n cache: cacheOptions?.cache,\n next: cacheOptions?.next,\n });\n }\n\n return {\n async getPosts(params) {\n const limit = params?.limit ?? 20;\n const cursorPage = params?.cursor ? Number(params.cursor) : undefined;\n const page = Number.isFinite(cursorPage) && cursorPage! >= 1 ? cursorPage! : 1;\n const data = await fetchBlogPage(limit, page, params);\n return {\n posts: data.items,\n nextCursor: data.pagination.hasMore ? String(data.pagination.page + 1) : undefined,\n };\n },\n async getPostBySlug(slug: string, options?: FetchRequestOptions) {\n if (!slug) {\n throw new ApiError(\"slug is required\", { status: 400 });\n }\n const workspaceSlug = ensureWorkspaceSlug();\n const post = await request<{ post: BlogPost } | null>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs/${encodeURIComponent(slug)}`,\n allowNotFound: true,\n cache: options?.cache,\n next: options?.next,\n });\n if (post === null) {\n return null;\n }\n return post.post;\n },\n async getSitemapEntries() {\n const entries: Array<{ slug: string; updatedAt: string }> = [];\n const limit = 100;\n let page = 1;\n\n while (true) {\n const pageData = await fetchBlogPage(limit, page);\n pageData.items.forEach((post) => {\n entries.push({ slug: post.slug, updatedAt: post.updatedAt });\n });\n\n if (!pageData.pagination.hasMore) {\n break;\n }\n\n page = pageData.pagination.page + 1;\n }\n\n return entries;\n },\n };\n}\n","import { createBlogAutoClient, type BlogAutoClient } from \"./client\";\n\nexport interface BlogAutoEnvConfig {\n client: BlogAutoClient;\n workspaceSlug: string;\n workspaceId?: string;\n siteUrl: string;\n revalidateSecret?: string;\n analyticsToken?: string;\n analyticsProxy: string;\n apiUrl: string;\n apiKey: string;\n tags: {\n posts: string;\n post: (slug: string) => string;\n sitemap: string;\n };\n}\n\nlet _instance: BlogAutoEnvConfig | null = null;\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\nexport function createBlogAutoFromEnv(): BlogAutoEnvConfig {\n if (_instance) {\n return _instance;\n }\n\n const apiUrl = process.env.BLOGAUTO_API_URL ?? \"https://api.blogauto.io\";\n const apiKey = requireEnv(\"BLOGAUTO_API_KEY\");\n const workspaceSlug = requireEnv(\"BLOGAUTO_WORKSPACE_SLUG\");\n const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;\n const siteUrl =\n process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? \"http://localhost:3000\";\n const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;\n const analyticsToken = process.env.NEXT_PUBLIC_ANALYTICS_TOKEN;\n const analyticsProxy =\n process.env.NEXT_PUBLIC_ANALYTICS_PROXY ?? \"/api/blogauto/analytics\";\n\n const client = createBlogAutoClient({\n apiUrl,\n apiKey,\n workspaceSlug,\n workspaceId,\n });\n\n _instance = {\n client,\n workspaceSlug,\n workspaceId,\n siteUrl,\n revalidateSecret,\n analyticsToken,\n analyticsProxy,\n apiUrl,\n apiKey,\n tags: {\n posts: `blogauto:${workspaceSlug}:posts`,\n post: (slug: string) => `blogauto:${workspaceSlug}:post:${slug}`,\n sitemap: `blogauto:${workspaceSlug}:sitemap`,\n },\n };\n\n return _instance;\n}\n","import type { BlogPost } from \"./types\";\n\nexport interface NextMetadata {\n title?: string;\n description?: string;\n keywords?: string[];\n alternates?: {\n canonical?: string;\n };\n openGraph?: {\n type?: string;\n title?: string;\n description?: string;\n images?: Array<{ url: string }>;\n publishedTime?: string;\n modifiedTime?: string;\n };\n twitter?: {\n card?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n}\n\nexport function buildNextMetadata(post: BlogPost): NextMetadata {\n const title = post.seo?.title ?? post.title;\n const description = post.seo?.description ?? post.excerpt;\n const keywords = post.seo?.keywords;\n const canonical = post.metadata?.canonicalUrl;\n const ogImageUrl = post.metadata?.ogImageUrl;\n\n const metadata: NextMetadata = {\n title,\n description,\n };\n\n if (keywords && keywords.length > 0) {\n metadata.keywords = keywords;\n }\n\n if (canonical) {\n metadata.alternates = { canonical };\n }\n\n metadata.openGraph = {\n type: \"article\",\n title,\n description,\n publishedTime: post.publishedAt,\n modifiedTime: post.updatedAt,\n };\n\n if (ogImageUrl) {\n metadata.openGraph.images = [{ url: ogImageUrl }];\n }\n\n metadata.twitter = {\n card: ogImageUrl ? \"summary_large_image\" : \"summary\",\n title,\n description,\n };\n\n if (ogImageUrl) {\n metadata.twitter.images = [ogImageUrl];\n }\n\n return metadata;\n}\n","import { BuildSitemapOptions, MetadataRouteSitemap, MetadataRouteSitemapEntry } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizeRoutePrefix(routePrefix?: string): string {\n if (!routePrefix || routePrefix === \"/\") {\n return \"\";\n }\n const withSlash = routePrefix.startsWith(\"/\") ? routePrefix : `/${routePrefix}`;\n return withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash;\n}\n\nfunction normalizeSlug(slug: string): string {\n return slug.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function buildSitemap(opts: BuildSitemapOptions): MetadataRouteSitemap {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const prefix = normalizeRoutePrefix(opts.routePrefix ?? \"/blog\");\n\n const entries: MetadataRouteSitemapEntry[] = opts.entries.map((entry) => {\n const slug = normalizeSlug(entry.slug);\n const hasSlug = slug.length > 0;\n const slugFragment = hasSlug ? `/${slug}` : \"\";\n const path = prefix ? `${prefix}${slugFragment}` : hasSlug ? `/${slug}` : \"/\";\n return {\n url: `${siteUrl}${path}`,\n lastModified: entry.updatedAt,\n };\n });\n\n return entries;\n}\n","import { BuildRobotsOptions, MetadataRouteRobots } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n if (!path) {\n return \"/sitemap.xml\";\n }\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n return path;\n}\n\nexport function buildRobots(opts: BuildRobotsOptions): MetadataRouteRobots {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const sitemapPath = normalizePath(opts.sitemapPath ?? \"/sitemap.xml\");\n const sitemapUrl = `${siteUrl}${sitemapPath}`;\n\n return {\n rules: [{ userAgent: \"*\", allow: \"/\" }],\n sitemap: sitemapUrl,\n };\n}\n","import { createBlogAutoFromEnv } from \"../env\";\nimport { buildNextMetadata, type NextMetadata } from \"../metadata\";\nimport { buildSitemap } from \"../sitemap\";\nimport { buildRobots } from \"../robots\";\nimport type { BlogPost, PostsResponse, MetadataRouteSitemap, MetadataRouteRobots } from \"../types\";\n\nexport interface FetchBlogPostsOptions {\n limit?: number;\n cursor?: string;\n}\n\nexport async function fetchBlogPosts(options?: FetchBlogPostsOptions): Promise<PostsResponse> {\n const { client, tags } = createBlogAutoFromEnv();\n return client.getPosts({\n limit: options?.limit,\n cursor: options?.cursor,\n next: { tags: [tags.posts] },\n });\n}\n\nexport async function fetchBlogPost(slug: string): Promise<BlogPost> {\n const { client, tags } = createBlogAutoFromEnv();\n const post = await client.getPostBySlug(slug, {\n next: { tags: [tags.post(slug)] },\n });\n\n if (!post) {\n // Dynamic import to avoid pulling next/navigation into non-Next environments\n const nav = await import(/* webpackIgnore: true */ \"next/navigation\" as string) as {\n notFound: () => never;\n };\n nav.notFound();\n // notFound() throws, but TS can't infer `never` through dynamic import\n throw new Error(\"notFound\");\n }\n\n return post;\n}\n\nexport async function generatePostMetadata(slug: string): Promise<NextMetadata> {\n const { client, tags } = createBlogAutoFromEnv();\n const post = await client.getPostBySlug(slug, {\n next: { tags: [tags.post(slug)] },\n });\n\n if (!post) {\n return {};\n }\n\n return buildNextMetadata(post);\n}\n\nexport async function generateBlogSitemap(): Promise<MetadataRouteSitemap> {\n const { client, siteUrl } = createBlogAutoFromEnv();\n const entries = await client.getSitemapEntries();\n return buildSitemap({ siteUrl, routePrefix: \"/blog\", entries });\n}\n\nexport function generateBlogRobots(): MetadataRouteRobots {\n const { siteUrl } = createBlogAutoFromEnv();\n return buildRobots({ siteUrl, sitemapPath: \"/sitemap.xml\" });\n}\n","import crypto from \"crypto\";\nimport type { BlogAutoRevalidatePayload, RevalidatePathFn, RevalidateTagFn } from \"./types\";\n\nexport interface VerifyWebhookSignatureOptions {\n rawBody: string | Buffer;\n signature: string | null;\n secret: string;\n}\n\nexport interface CreateRevalidateRouteHandlerOptions {\n secret: string;\n allowedSkewSeconds?: number;\n revalidatePath?: RevalidatePathFn;\n revalidateTag?: RevalidateTagFn;\n revalidatePaths?: (payload: BlogAutoRevalidatePayload) => string[];\n revalidateTags?: (payload: BlogAutoRevalidatePayload) => string[];\n}\n\ninterface JsonResponseInit extends ResponseInit {\n status?: number;\n}\n\nfunction jsonResponse(body: unknown, init?: JsonResponseInit): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"content-type\", \"application/json\");\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeSignature(signature: string | null): Buffer | null {\n if (!signature) {\n return null;\n }\n const trimmed = signature.trim();\n if (!trimmed) {\n return null;\n }\n\n const withoutPrefix = trimmed.startsWith(\"sha256=\") ? trimmed.slice(7) : trimmed;\n if (!withoutPrefix) {\n return null;\n }\n\n try {\n return Buffer.from(withoutPrefix, \"hex\");\n } catch {\n return null;\n }\n}\n\nexport function verifyWebhookSignature(opts: VerifyWebhookSignatureOptions): boolean {\n const { rawBody, signature, secret } = opts;\n if (!secret) {\n throw new Error(\"Secret is required to verify webhook signatures\");\n }\n const providedSignature = normalizeSignature(signature);\n if (!providedSignature) {\n return false;\n }\n\n const bodyBuffer = typeof rawBody === \"string\" ? Buffer.from(rawBody) : rawBody;\n const expected = crypto.createHmac(\"sha256\", secret).update(bodyBuffer).digest();\n\n if (providedSignature.length !== expected.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedSignature, expected);\n}\n\nfunction defaultPaths(payload: BlogAutoRevalidatePayload): string[] {\n const paths = new Set<string>([\"/sitemap.xml\", \"/robots.txt\", \"/blog\"]);\n if (payload.postSlug) {\n paths.add(`/blog/${payload.postSlug}`);\n }\n return Array.from(paths);\n}\n\nfunction defaultTags(payload: BlogAutoRevalidatePayload): string[] {\n const tags = new Set<string>();\n if (payload.workspaceSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:sitemap`);\n tags.add(`blogauto:${payload.workspaceSlug}:posts`);\n if (payload.postSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:post:${payload.postSlug}`);\n }\n }\n return Array.from(tags);\n}\n\nfunction dedupe(values: string[] | undefined): string[] {\n if (!values || values.length === 0) {\n return [];\n }\n return Array.from(\n new Set(\n values\n .filter((value) => typeof value === \"string\" && value.trim().length > 0)\n .map((value) => value.trim()),\n ),\n );\n}\n\nfunction determineRouteType(path: string): \"route\" | \"page\" {\n const lower = path.toLowerCase();\n if (lower.endsWith(\".xml\") || lower.endsWith(\".txt\")) {\n return \"route\";\n }\n return \"page\";\n}\n\nexport function createRevalidateRouteHandler(\n options: CreateRevalidateRouteHandlerOptions,\n): (request: Request) => Promise<Response> {\n if (!options.secret) {\n throw new Error(\"secret is required for createRevalidateRouteHandler\");\n }\n\n const allowedSkewMs = Math.max(1, options.allowedSkewSeconds ?? 300) * 1000;\n const pathBuilder = options.revalidatePaths ?? defaultPaths;\n const tagBuilder = options.revalidateTags ?? defaultTags;\n\n return async function blogAutoRevalidateHandler(request: Request): Promise<Response> {\n const signature = request.headers.get(\"x-blogauto-signature\");\n const receivedAt = Date.now();\n\n const rawBody = await request.text();\n const isValid = verifyWebhookSignature({\n rawBody,\n signature,\n secret: options.secret,\n });\n\n if (!isValid) {\n return jsonResponse({ error: \"Invalid webhook signature\" }, { status: 401 });\n }\n\n let payload: BlogAutoRevalidatePayload;\n try {\n payload = JSON.parse(rawBody) as BlogAutoRevalidatePayload;\n } catch {\n return jsonResponse({ error: \"Invalid JSON payload\" }, { status: 400 });\n }\n\n if (!payload.workspaceSlug || typeof payload.workspaceSlug !== \"string\") {\n return jsonResponse({ error: \"workspaceSlug is required\" }, { status: 400 });\n }\n\n if (!payload.ts || typeof payload.ts !== \"string\") {\n return jsonResponse({ error: \"Timestamp is required\" }, { status: 400 });\n }\n\n const payloadTs = Date.parse(payload.ts);\n if (Number.isNaN(payloadTs)) {\n return jsonResponse({ error: \"Invalid timestamp\" }, { status: 400 });\n }\n\n if (Math.abs(receivedAt - payloadTs) > allowedSkewMs) {\n return jsonResponse({ error: \"Webhook timestamp is outside allowed skew\" }, { status: 409 });\n }\n\n const paths = dedupe(pathBuilder(payload));\n const tags = dedupe(tagBuilder(payload));\n\n try {\n if (options.revalidatePath && paths.length > 0) {\n await Promise.all(\n paths.map((path) => options.revalidatePath!(path, determineRouteType(path))),\n );\n }\n\n if (options.revalidateTag && tags.length > 0) {\n await Promise.all(tags.map((tag) => options.revalidateTag!(tag)));\n }\n } catch (error) {\n return jsonResponse(\n { error: \"Failed to revalidate cache\", details: (error as Error).message },\n { status: 500 },\n );\n }\n\n return jsonResponse({\n ok: true,\n event: payload.event ?? \"post.published\",\n revalidated: {\n paths,\n tags,\n },\n });\n };\n}\n","import { createBlogAutoFromEnv } from \"../env\";\nimport { createRevalidateRouteHandler } from \"../revalidate\";\nimport { buildAuthHeaders } from \"../auth\";\n\nexport function createEnvRevalidateHandler(): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n // Lazy init so env vars are read at request time, not module load time\n const { revalidateSecret } = createBlogAutoFromEnv();\n\n if (!revalidateSecret) {\n return new Response(\n JSON.stringify({ error: \"Missing BLOGAUTO_REVALIDATE_SECRET\" }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n\n // Dynamic import to avoid pulling next/cache into non-Next environments\n const nextCache = await import(/* webpackIgnore: true */ \"next/cache\" as string) as {\n revalidatePath: (path: string, type?: \"page\" | \"layout\" | \"route\") => void;\n revalidateTag: (tag: string) => void;\n };\n const { revalidatePath, revalidateTag } = nextCache;\n\n const handler = createRevalidateRouteHandler({\n secret: revalidateSecret,\n revalidatePath,\n revalidateTag,\n });\n\n return handler(request);\n };\n}\n\nexport function createEnvAnalyticsHandler(): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n const { analyticsToken, apiUrl, apiKey, workspaceId, workspaceSlug } =\n createBlogAutoFromEnv();\n\n if (!analyticsToken) {\n return new Response(\n JSON.stringify({ error: \"Analytics proxy disabled\" }),\n { status: 503, headers: { \"content-type\": \"application/json\" } },\n );\n }\n\n const provided = request.headers.get(\"x-api-key\");\n if (provided !== analyticsToken) {\n return new Response(\n JSON.stringify({ error: \"Unauthorized\" }),\n { status: 401, headers: { \"content-type\": \"application/json\" } },\n );\n }\n\n const payload = await request.json();\n const envelope = {\n ...payload,\n workspaceId: workspaceId ?? payload.workspaceId,\n workspaceSlug: workspaceSlug ?? payload.workspaceSlug,\n };\n\n const response = await fetch(`${apiUrl}/v1/analytics/ingest`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...buildAuthHeaders(apiKey, \"bearer\"),\n },\n body: JSON.stringify(envelope),\n });\n\n const text = await response.text();\n const contentType = response.headers.get(\"content-type\") ?? \"application/json\";\n\n return new Response(text || \"{}\", {\n status: response.status,\n headers: { \"content-type\": contentType },\n });\n };\n}\n"],"mappings":"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","names":["normalizeSiteUrl"]}
1
+ {"version":3,"sources":["../src/auth.ts","../src/errors.ts","../src/utils.ts","../src/client.ts","../src/env.ts","../src/metadata.ts","../src/sitemap.ts","../src/robots.ts","../src/next/helpers.ts","../src/revalidate.ts","../src/next/route-handlers.ts"],"sourcesContent":["import { AuthMode } from \"./types\";\n\nexport function buildAuthHeaders(apiKey: string, authMode: AuthMode = \"bearer\"): Record<string, string> {\n if (authMode === \"x-api-key\") {\n return { \"x-api-key\": apiKey };\n }\n return { Authorization: `Bearer ${apiKey}` };\n}\n","export class BlogAutoError extends Error {\n public readonly causeError?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = new.target.name;\n this.causeError = options?.cause;\n }\n}\n\nexport class ConfigError extends BlogAutoError {}\n\nexport interface ApiErrorDetails {\n status: number;\n code?: string;\n details?: unknown;\n}\n\nexport class ApiError extends BlogAutoError {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, info: ApiErrorDetails, options?: { cause?: unknown }) {\n super(message, options);\n this.status = info.status;\n this.code = info.code;\n this.details = info.details;\n }\n}\n\nexport class NotFoundError extends ApiError {\n constructor(message: string, info?: Partial<ApiErrorDetails>) {\n super(message, { status: info?.status ?? 404, code: info?.code, details: info?.details });\n }\n}\n","import { ApiError, ConfigError } from \"./errors\";\nimport { AuthMode, BlogAutoClientConfig, InternalClientConfig } from \"./types\";\n\nexport const DEFAULT_TIMEOUT_MS = 10_000;\n\nexport function normalizeApiUrl(apiUrl: string): string {\n if (!apiUrl) {\n throw new ConfigError(\"apiUrl is required\");\n }\n\n return apiUrl.replace(/\\/$/, \"\");\n}\n\nexport function resolveClientConfig(config: BlogAutoClientConfig): InternalClientConfig {\n if (!config) {\n throw new ConfigError(\"Client configuration is required\");\n }\n\n const apiKey = config.apiKey?.trim();\n if (!apiKey) {\n throw new ConfigError(\"apiKey is required to authenticate with BlogAuto\");\n }\n\n if (!config.workspaceId && !config.workspaceSlug) {\n throw new ConfigError(\"Provide either workspaceId or workspaceSlug\");\n }\n\n const authMode: AuthMode = config.authMode ?? \"bearer\";\n\n return {\n apiKey,\n apiUrl: normalizeApiUrl(config.apiUrl),\n workspaceId: config.workspaceId,\n workspaceSlug: config.workspaceSlug,\n authMode,\n fetch: config.fetch ?? globalThis.fetch.bind(globalThis),\n headers: { ...(config.headers ?? {}) },\n timeoutMs: config.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n };\n}\n\nexport function buildQuery(params: Record<string, string | number | undefined | null>): string {\n const query = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value === undefined || value === null || value === \"\") {\n return;\n }\n query.set(key, String(value));\n });\n const qs = query.toString();\n return qs ? `?${qs}` : \"\";\n}\n\nexport async function withTimeout<T>(promise: Promise<T>, timeoutMs?: number): Promise<T> {\n if (!timeoutMs) {\n return promise;\n }\n\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new ApiError(`Request timed out after ${timeoutMs}ms`, {\n status: 408,\n }),\n );\n }, timeoutMs);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: Array<Record<string, string> | undefined>\n): Record<string, string> {\n return headerObjects.reduce<Record<string, string>>((acc, headers) => {\n if (!headers) {\n return acc;\n }\n Object.entries(headers).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n acc[key.toLowerCase()] = value;\n });\n return acc;\n }, {});\n}\n","import { buildAuthHeaders } from \"./auth\";\nimport { ApiError, BlogAutoError, ConfigError } from \"./errors\";\nimport { buildQuery, mergeHeaders, resolveClientConfig, withTimeout } from \"./utils\";\nimport type {\n BlogAutoClientConfig,\n BlogPost,\n FetchRequestOptions,\n PaginatedList,\n PostsResponse,\n} from \"./types\";\n\ninterface RequestOptions {\n path: string;\n method?: string;\n query?: Record<string, string | number | undefined | null>;\n body?: unknown;\n allowNotFound?: boolean;\n headers?: Record<string, string>;\n cache?: RequestCache;\n next?: FetchRequestOptions[\"next\"];\n}\n\nexport interface BlogAutoClient {\n getPosts(params?: { limit?: number; cursor?: string } & FetchRequestOptions): Promise<PostsResponse>;\n getPostBySlug(slug: string, options?: FetchRequestOptions): Promise<BlogPost | null>;\n getSitemapEntries(): Promise<Array<{ slug: string; updatedAt: string }>>;\n}\n\nexport function createBlogAutoClient(config: BlogAutoClientConfig): BlogAutoClient {\n const resolved = resolveClientConfig(config);\n const fetchImpl = resolved.fetch;\n const debug =\n typeof process !== \"undefined\" &&\n typeof process.env !== \"undefined\" &&\n process.env.BLOGAUTO_DEBUG === \"true\";\n const debugLog = (...args: unknown[]) => {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\"[blogauto]\", ...args);\n }\n };\n\n function ensureWorkspaceSlug(): string {\n if (!resolved.workspaceSlug) {\n throw new ConfigError(\"workspaceSlug is required to call the BlogAuto public API\");\n }\n return resolved.workspaceSlug;\n }\n\n function buildUrl(path: string, query?: Record<string, string | number | undefined | null>): string {\n const qs = buildQuery(query ?? {});\n return `${resolved.apiUrl}${path}${qs}`;\n }\n\n function unwrapSuccessPayload<T>(payload: unknown): T {\n if (payload && typeof payload === \"object\") {\n const maybePayload = payload as { success?: boolean; data?: T; error?: { message?: string } };\n if (\"success\" in maybePayload) {\n if (maybePayload.success === false) {\n throw new ApiError(\n maybePayload.error?.message ?? \"BlogAuto request failed\",\n { status: 500, details: maybePayload },\n );\n }\n if (maybePayload.success && \"data\" in maybePayload) {\n return maybePayload.data as T;\n }\n }\n }\n return payload as T;\n }\n\n async function request<T>(opts: RequestOptions): Promise<T> {\n const method = opts.method ?? \"GET\";\n const url = buildUrl(opts.path, opts.query);\n\n const authHeaders = buildAuthHeaders(resolved.apiKey, resolved.authMode);\n const baseHeaders = mergeHeaders(resolved.headers, authHeaders, opts.headers);\n\n const init: RequestInit = {\n method,\n headers: baseHeaders,\n };\n\n if (opts.body) {\n init.body = typeof opts.body === \"string\" ? opts.body : JSON.stringify(opts.body);\n init.headers = {\n ...baseHeaders,\n \"content-type\": baseHeaders[\"content-type\"] ?? \"application/json\",\n };\n }\n\n if (opts.cache !== undefined) {\n init.cache = opts.cache;\n }\n\n if (opts.next) {\n (init as RequestInit & { next?: FetchRequestOptions[\"next\"] }).next = opts.next;\n }\n\n const startedAt = Date.now();\n try {\n const response = await withTimeout(fetchImpl(url, init), resolved.timeoutMs);\n debugLog(\"response\", {\n method,\n url,\n status: response.status,\n durationMs: Date.now() - startedAt,\n });\n if (opts.allowNotFound && response.status === 404) {\n return null as T;\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n const payload = isJson ? await response.json().catch(() => undefined) : await response.text();\n\n if (!response.ok) {\n if (response.status === 404 && opts.allowNotFound) {\n return null as T;\n }\n\n const errorBody = payload as any;\n const message =\n errorBody?.error?.message ?? errorBody?.message ?? `Request failed with status ${response.status}`;\n throw new ApiError(message, {\n status: response.status,\n code: errorBody?.error?.code ?? errorBody?.code,\n details: errorBody?.error?.details ?? errorBody,\n });\n }\n\n if (isJson) {\n return unwrapSuccessPayload<T>(payload);\n }\n\n return (payload as T) ?? (undefined as T);\n } catch (error) {\n debugLog(\"request failed\", {\n method,\n url,\n durationMs: Date.now() - startedAt,\n error: error instanceof Error ? error.message : error,\n });\n if (error instanceof BlogAutoError) {\n throw error;\n }\n const causeMessage =\n error instanceof Error ? error.message : typeof error === \"string\" ? error : undefined;\n const message = causeMessage\n ? `Network request to BlogAuto failed: ${causeMessage}`\n : \"Network request to BlogAuto failed\";\n throw new ApiError(\n message,\n {\n status: 0,\n details: { url, method },\n },\n { cause: error },\n );\n }\n }\n\n async function fetchBlogPage(\n limit: number,\n page: number,\n cacheOptions?: FetchRequestOptions,\n ): Promise<PaginatedList<BlogPost>> {\n const workspaceSlug = ensureWorkspaceSlug();\n debugLog(\"fetch posts page\", { workspaceSlug, limit, page });\n return request<PaginatedList<BlogPost>>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs`,\n query: { limit, page },\n cache: cacheOptions?.cache,\n next: cacheOptions?.next,\n });\n }\n\n return {\n async getPosts(params) {\n const limit = params?.limit ?? 20;\n const cursorPage = params?.cursor ? Number(params.cursor) : undefined;\n const page = Number.isFinite(cursorPage) && cursorPage! >= 1 ? cursorPage! : 1;\n const data = await fetchBlogPage(limit, page, params);\n return {\n posts: data.items,\n nextCursor: data.pagination.hasMore ? String(data.pagination.page + 1) : undefined,\n };\n },\n async getPostBySlug(slug: string, options?: FetchRequestOptions) {\n if (!slug) {\n throw new ApiError(\"slug is required\", { status: 400 });\n }\n const workspaceSlug = ensureWorkspaceSlug();\n const post = await request<{ post: BlogPost } | null>({\n path: `/v1/public/${encodeURIComponent(workspaceSlug)}/blogs/${encodeURIComponent(slug)}`,\n allowNotFound: true,\n cache: options?.cache,\n next: options?.next,\n });\n if (post === null) {\n return null;\n }\n return post.post;\n },\n async getSitemapEntries() {\n const entries: Array<{ slug: string; updatedAt: string }> = [];\n const limit = 100;\n let page = 1;\n\n while (true) {\n const pageData = await fetchBlogPage(limit, page);\n pageData.items.forEach((post) => {\n entries.push({ slug: post.slug, updatedAt: post.updatedAt });\n });\n\n if (!pageData.pagination.hasMore) {\n break;\n }\n\n page = pageData.pagination.page + 1;\n }\n\n return entries;\n },\n };\n}\n","import { createBlogAutoClient, type BlogAutoClient } from \"./client\";\n\nexport interface BlogAutoEnvConfig {\n client: BlogAutoClient;\n workspaceSlug: string;\n workspaceId?: string;\n siteUrl: string;\n revalidateSecret?: string;\n apiUrl: string;\n apiKey: string;\n tags: {\n posts: string;\n post: (slug: string) => string;\n sitemap: string;\n };\n}\n\nlet _instance: BlogAutoEnvConfig | null = null;\n\nfunction requireEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n\nexport function createBlogAutoFromEnv(): BlogAutoEnvConfig {\n if (_instance) {\n return _instance;\n }\n\n const apiUrl = process.env.BLOGAUTO_API_URL ?? \"https://api.blogauto.io\";\n const apiKey = requireEnv(\"BLOGAUTO_API_KEY\");\n const workspaceSlug = requireEnv(\"BLOGAUTO_WORKSPACE_SLUG\");\n const workspaceId = process.env.BLOGAUTO_WORKSPACE_ID;\n const siteUrl =\n process.env.SITE_URL ?? process.env.NEXT_PUBLIC_SITE_URL ?? \"http://localhost:3000\";\n const revalidateSecret = process.env.BLOGAUTO_REVALIDATE_SECRET;\n\n const client = createBlogAutoClient({\n apiUrl,\n apiKey,\n workspaceSlug,\n workspaceId,\n });\n\n _instance = {\n client,\n workspaceSlug,\n workspaceId,\n siteUrl,\n revalidateSecret,\n apiUrl,\n apiKey,\n tags: {\n posts: `blogauto:${workspaceSlug}:posts`,\n post: (slug: string) => `blogauto:${workspaceSlug}:post:${slug}`,\n sitemap: `blogauto:${workspaceSlug}:sitemap`,\n },\n };\n\n return _instance;\n}\n","import type { BlogPost } from \"./types\";\n\nexport interface NextMetadata {\n title?: string;\n description?: string;\n keywords?: string[];\n alternates?: {\n canonical?: string;\n };\n openGraph?: {\n type?: string;\n title?: string;\n description?: string;\n images?: Array<{ url: string }>;\n publishedTime?: string;\n modifiedTime?: string;\n };\n twitter?: {\n card?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n}\n\nexport function buildNextMetadata(post: BlogPost): NextMetadata {\n const title = post.seo?.title ?? post.title;\n const description = post.seo?.description ?? post.excerpt;\n const keywords = post.seo?.keywords;\n const canonical = post.metadata?.canonicalUrl;\n const ogImageUrl = post.metadata?.ogImageUrl;\n\n const metadata: NextMetadata = {\n title,\n description,\n };\n\n if (keywords && keywords.length > 0) {\n metadata.keywords = keywords;\n }\n\n if (canonical) {\n metadata.alternates = { canonical };\n }\n\n metadata.openGraph = {\n type: \"article\",\n title,\n description,\n publishedTime: post.publishedAt,\n modifiedTime: post.updatedAt,\n };\n\n if (ogImageUrl) {\n metadata.openGraph.images = [{ url: ogImageUrl }];\n }\n\n metadata.twitter = {\n card: ogImageUrl ? \"summary_large_image\" : \"summary\",\n title,\n description,\n };\n\n if (ogImageUrl) {\n metadata.twitter.images = [ogImageUrl];\n }\n\n return metadata;\n}\n","import { BuildSitemapOptions, MetadataRouteSitemap, MetadataRouteSitemapEntry } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizeRoutePrefix(routePrefix?: string): string {\n if (!routePrefix || routePrefix === \"/\") {\n return \"\";\n }\n const withSlash = routePrefix.startsWith(\"/\") ? routePrefix : `/${routePrefix}`;\n return withSlash.endsWith(\"/\") ? withSlash.slice(0, -1) : withSlash;\n}\n\nfunction normalizeSlug(slug: string): string {\n return slug.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function buildSitemap(opts: BuildSitemapOptions): MetadataRouteSitemap {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const prefix = normalizeRoutePrefix(opts.routePrefix ?? \"/blog\");\n\n const entries: MetadataRouteSitemapEntry[] = opts.entries.map((entry) => {\n const slug = normalizeSlug(entry.slug);\n const hasSlug = slug.length > 0;\n const slugFragment = hasSlug ? `/${slug}` : \"\";\n const path = prefix ? `${prefix}${slugFragment}` : hasSlug ? `/${slug}` : \"/\";\n return {\n url: `${siteUrl}${path}`,\n lastModified: entry.updatedAt,\n };\n });\n\n return entries;\n}\n","import { BuildRobotsOptions, MetadataRouteRobots } from \"./types\";\n\nfunction normalizeSiteUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n if (!path) {\n return \"/sitemap.xml\";\n }\n if (!path.startsWith(\"/\")) {\n return `/${path}`;\n }\n return path;\n}\n\nexport function buildRobots(opts: BuildRobotsOptions): MetadataRouteRobots {\n const siteUrl = normalizeSiteUrl(opts.siteUrl);\n const sitemapPath = normalizePath(opts.sitemapPath ?? \"/sitemap.xml\");\n const sitemapUrl = `${siteUrl}${sitemapPath}`;\n\n return {\n rules: [{ userAgent: \"*\", allow: \"/\" }],\n sitemap: sitemapUrl,\n };\n}\n","import { createBlogAutoFromEnv } from \"../env\";\nimport { buildNextMetadata, type NextMetadata } from \"../metadata\";\nimport { buildSitemap } from \"../sitemap\";\nimport { buildRobots } from \"../robots\";\nimport type { BlogPost, PostsResponse, MetadataRouteSitemap, MetadataRouteRobots } from \"../types\";\n\nexport interface FetchBlogPostsOptions {\n limit?: number;\n cursor?: string;\n}\n\nexport async function fetchBlogPosts(options?: FetchBlogPostsOptions): Promise<PostsResponse> {\n const { client, tags } = createBlogAutoFromEnv();\n return client.getPosts({\n limit: options?.limit,\n cursor: options?.cursor,\n next: { tags: [tags.posts] },\n });\n}\n\nexport async function fetchBlogPost(slug: string): Promise<BlogPost> {\n const { client, tags } = createBlogAutoFromEnv();\n const post = await client.getPostBySlug(slug, {\n next: { tags: [tags.post(slug)] },\n });\n\n if (!post) {\n // Dynamic import to avoid pulling next/navigation into non-Next environments\n const nav = await import(/* webpackIgnore: true */ \"next/navigation\" as string) as {\n notFound: () => never;\n };\n nav.notFound();\n // notFound() throws, but TS can't infer `never` through dynamic import\n throw new Error(\"notFound\");\n }\n\n return post;\n}\n\nexport async function generatePostMetadata(slug: string): Promise<NextMetadata> {\n const { client, tags } = createBlogAutoFromEnv();\n const post = await client.getPostBySlug(slug, {\n next: { tags: [tags.post(slug)] },\n });\n\n if (!post) {\n return {};\n }\n\n return buildNextMetadata(post);\n}\n\nexport async function generateBlogSitemap(): Promise<MetadataRouteSitemap> {\n const { client, siteUrl } = createBlogAutoFromEnv();\n const entries = await client.getSitemapEntries();\n return buildSitemap({ siteUrl, routePrefix: \"/blog\", entries });\n}\n\nexport function generateBlogRobots(): MetadataRouteRobots {\n const { siteUrl } = createBlogAutoFromEnv();\n return buildRobots({ siteUrl, sitemapPath: \"/sitemap.xml\" });\n}\n","import crypto from \"crypto\";\nimport type { BlogAutoRevalidatePayload, RevalidatePathFn, RevalidateTagFn } from \"./types\";\n\nexport interface VerifyWebhookSignatureOptions {\n rawBody: string | Buffer;\n signature: string | null;\n secret: string;\n}\n\nexport interface CreateRevalidateRouteHandlerOptions {\n secret: string;\n allowedSkewSeconds?: number;\n revalidatePath?: RevalidatePathFn;\n revalidateTag?: RevalidateTagFn;\n revalidatePaths?: (payload: BlogAutoRevalidatePayload) => string[];\n revalidateTags?: (payload: BlogAutoRevalidatePayload) => string[];\n}\n\ninterface JsonResponseInit extends ResponseInit {\n status?: number;\n}\n\nfunction jsonResponse(body: unknown, init?: JsonResponseInit): Response {\n const headers = new Headers(init?.headers);\n headers.set(\"content-type\", \"application/json\");\n return new Response(JSON.stringify(body), {\n ...init,\n headers,\n });\n}\n\nfunction normalizeSignature(signature: string | null): Buffer | null {\n if (!signature) {\n return null;\n }\n const trimmed = signature.trim();\n if (!trimmed) {\n return null;\n }\n\n const withoutPrefix = trimmed.startsWith(\"sha256=\") ? trimmed.slice(7) : trimmed;\n if (!withoutPrefix) {\n return null;\n }\n\n try {\n return Buffer.from(withoutPrefix, \"hex\");\n } catch {\n return null;\n }\n}\n\nexport function verifyWebhookSignature(opts: VerifyWebhookSignatureOptions): boolean {\n const { rawBody, signature, secret } = opts;\n if (!secret) {\n throw new Error(\"Secret is required to verify webhook signatures\");\n }\n const providedSignature = normalizeSignature(signature);\n if (!providedSignature) {\n return false;\n }\n\n const bodyBuffer = typeof rawBody === \"string\" ? Buffer.from(rawBody) : rawBody;\n const expected = crypto.createHmac(\"sha256\", secret).update(bodyBuffer).digest();\n\n if (providedSignature.length !== expected.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(providedSignature, expected);\n}\n\nfunction defaultPaths(payload: BlogAutoRevalidatePayload): string[] {\n const paths = new Set<string>([\"/sitemap.xml\", \"/robots.txt\", \"/blog\"]);\n if (payload.postSlug) {\n paths.add(`/blog/${payload.postSlug}`);\n }\n return Array.from(paths);\n}\n\nfunction defaultTags(payload: BlogAutoRevalidatePayload): string[] {\n const tags = new Set<string>();\n if (payload.workspaceSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:sitemap`);\n tags.add(`blogauto:${payload.workspaceSlug}:posts`);\n if (payload.postSlug) {\n tags.add(`blogauto:${payload.workspaceSlug}:post:${payload.postSlug}`);\n }\n }\n return Array.from(tags);\n}\n\nfunction dedupe(values: string[] | undefined): string[] {\n if (!values || values.length === 0) {\n return [];\n }\n return Array.from(\n new Set(\n values\n .filter((value) => typeof value === \"string\" && value.trim().length > 0)\n .map((value) => value.trim()),\n ),\n );\n}\n\nfunction determineRouteType(path: string): \"route\" | \"page\" {\n const lower = path.toLowerCase();\n if (lower.endsWith(\".xml\") || lower.endsWith(\".txt\")) {\n return \"route\";\n }\n return \"page\";\n}\n\nexport function createRevalidateRouteHandler(\n options: CreateRevalidateRouteHandlerOptions,\n): (request: Request) => Promise<Response> {\n if (!options.secret) {\n throw new Error(\"secret is required for createRevalidateRouteHandler\");\n }\n\n const allowedSkewMs = Math.max(1, options.allowedSkewSeconds ?? 300) * 1000;\n const pathBuilder = options.revalidatePaths ?? defaultPaths;\n const tagBuilder = options.revalidateTags ?? defaultTags;\n\n return async function blogAutoRevalidateHandler(request: Request): Promise<Response> {\n const signature = request.headers.get(\"x-blogauto-signature\");\n const receivedAt = Date.now();\n\n const rawBody = await request.text();\n const isValid = verifyWebhookSignature({\n rawBody,\n signature,\n secret: options.secret,\n });\n\n if (!isValid) {\n return jsonResponse({ error: \"Invalid webhook signature\" }, { status: 401 });\n }\n\n let payload: BlogAutoRevalidatePayload;\n try {\n payload = JSON.parse(rawBody) as BlogAutoRevalidatePayload;\n } catch {\n return jsonResponse({ error: \"Invalid JSON payload\" }, { status: 400 });\n }\n\n if (!payload.workspaceSlug || typeof payload.workspaceSlug !== \"string\") {\n return jsonResponse({ error: \"workspaceSlug is required\" }, { status: 400 });\n }\n\n if (!payload.ts || typeof payload.ts !== \"string\") {\n return jsonResponse({ error: \"Timestamp is required\" }, { status: 400 });\n }\n\n const payloadTs = Date.parse(payload.ts);\n if (Number.isNaN(payloadTs)) {\n return jsonResponse({ error: \"Invalid timestamp\" }, { status: 400 });\n }\n\n if (Math.abs(receivedAt - payloadTs) > allowedSkewMs) {\n return jsonResponse({ error: \"Webhook timestamp is outside allowed skew\" }, { status: 409 });\n }\n\n const paths = dedupe(pathBuilder(payload));\n const tags = dedupe(tagBuilder(payload));\n\n try {\n if (options.revalidatePath && paths.length > 0) {\n await Promise.all(\n paths.map((path) => options.revalidatePath!(path, determineRouteType(path))),\n );\n }\n\n if (options.revalidateTag && tags.length > 0) {\n await Promise.all(tags.map((tag) => options.revalidateTag!(tag)));\n }\n } catch (error) {\n return jsonResponse(\n { error: \"Failed to revalidate cache\", details: (error as Error).message },\n { status: 500 },\n );\n }\n\n return jsonResponse({\n ok: true,\n event: payload.event ?? \"post.published\",\n revalidated: {\n paths,\n tags,\n },\n });\n };\n}\n","import { createBlogAutoFromEnv } from \"../env\";\nimport { createRevalidateRouteHandler } from \"../revalidate\";\n\nexport function createEnvRevalidateHandler(): (request: Request) => Promise<Response> {\n return async (request: Request): Promise<Response> => {\n // Lazy init so env vars are read at request time, not module load time\n const { revalidateSecret } = createBlogAutoFromEnv();\n\n if (!revalidateSecret) {\n return new Response(\n JSON.stringify({ error: \"Missing BLOGAUTO_REVALIDATE_SECRET\" }),\n { status: 500, headers: { \"content-type\": \"application/json\" } },\n );\n }\n\n // Dynamic import to avoid pulling next/cache into non-Next environments\n const nextCache = await import(/* webpackIgnore: true */ \"next/cache\" as string) as {\n revalidatePath: (path: string, type?: \"page\" | \"layout\" | \"route\") => void;\n revalidateTag: (tag: string) => void;\n };\n const { revalidatePath, revalidateTag } = nextCache;\n\n const handler = createRevalidateRouteHandler({\n secret: revalidateSecret,\n revalidatePath,\n revalidateTag,\n });\n\n return handler(request);\n };\n}\n"],"mappings":"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","names":["normalizeSiteUrl"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@autoblogwriter/sdk",
3
- "version": "2.0.0",
4
- "description": "Official BlogAuto SDK for fetching posts, building sitemaps, rendering helpers, and revalidation utilities.",
3
+ "version": "2.0.2",
4
+ "description": "Official AutoBlogWriter SDK for fetching posts, building sitemaps, rendering helpers, and revalidation utilities.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "dist/index.cjs",