@roottale/cms-renderer-next 0.53.1 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/{blog-filter-BKCGM0qd.d.ts → blog-filter-BQNQL3Mk.d.ts} +5 -0
- package/dist/{chunk-HM5VP7SR.js → chunk-FJANIAZN.js} +1 -1
- package/dist/chunk-FJANIAZN.js.map +1 -0
- package/dist/cms-public.css +23 -0
- package/dist/routes.d.ts +17 -2
- package/dist/routes.js +17 -3
- package/dist/routes.js.map +1 -1
- package/dist/server.d.ts +27 -3
- package/dist/server.js +70 -11
- package/dist/server.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-HM5VP7SR.js.map +0 -1
package/dist/server.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { CmsPostContent, RootTaleTheme, CmsPostType } from '@roottale/cms-client
|
|
|
3
3
|
export { RootTaleTheme } from '@roottale/cms-client/server';
|
|
4
4
|
import { RootTaleThemeStyle } from '@roottale/ui-react/theme';
|
|
5
5
|
import { Block, BindingResolver, RouteCollection } from '@roottale/cms-core';
|
|
6
|
-
export { a as BlogCategory, B as BlogCategoryWithCount, c as collectCategories, b as collectCategoriesWithCounts, d as defaultCategoryHref, f as filterPostsByCategory } from './blog-filter-
|
|
6
|
+
export { a as BlogCategory, B as BlogCategoryWithCount, c as collectCategories, b as collectCategoriesWithCounts, d as defaultCategoryHref, f as filterPostsByCategory } from './blog-filter-BQNQL3Mk.js';
|
|
7
7
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -238,7 +238,16 @@ declare function RootTaleBlogCategories(props: RootTaleBlogCategoriesProps): Pro
|
|
|
238
238
|
|
|
239
239
|
type RootTaleBlogPostProps = {
|
|
240
240
|
apiKey: string;
|
|
241
|
-
|
|
241
|
+
/** 발행 글 slug 또는 id. `previewToken` 을 줄 때는 생략할 수 있다. */
|
|
242
|
+
slugOrId?: string;
|
|
243
|
+
/**
|
|
244
|
+
* 어드민 편집기가 발급한 미리보기 토큰(URL `?token=`). 주면 `slugOrId` 대신
|
|
245
|
+
* `fetchPostPreview` 로 초안을 받아 **같은 템플릿**으로 그린다 — 미리보기 = 결과물.
|
|
246
|
+
* 만료(410)면 `previewExpiredElement`, 없으면(404) `notFoundElement`.
|
|
247
|
+
*/
|
|
248
|
+
previewToken?: string;
|
|
249
|
+
/** 미리보기 토큰이 만료됐을 때 대신 그릴 요소(기본: 만료 안내 문구). */
|
|
250
|
+
previewExpiredElement?: ReactElement;
|
|
242
251
|
baseUrl?: string;
|
|
243
252
|
notFoundElement?: ReactElement;
|
|
244
253
|
showTitle?: boolean;
|
|
@@ -270,6 +279,21 @@ declare function RootTaleFaqJsonLd({ doc, }: {
|
|
|
270
279
|
readonly doc: unknown;
|
|
271
280
|
}): ReactElement | null;
|
|
272
281
|
|
|
282
|
+
interface RootTalePreviewNoticeProps {
|
|
283
|
+
/** `ko`(기본) · `en`. */
|
|
284
|
+
locale?: string;
|
|
285
|
+
/** 기본 안내 문구를 바꾸고 싶을 때. */
|
|
286
|
+
message?: string;
|
|
287
|
+
/** 토큰 만료 시각(ISO) — 주면 "HH:MM까지" 를 덧붙인다. */
|
|
288
|
+
expiresAt?: string;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* 미리보기 화면 상단 안내 띠. 본문 템플릿은 발행 화면과 완전히 같게 두고, "이건
|
|
292
|
+
* 미리보기다" 라는 신호만 이 띠 하나로 준다. 검색엔진 색인 차단은 metadata
|
|
293
|
+
* (`buildPreviewMetadata`) 몫이며, 이 컴포넌트는 사람용 안내다.
|
|
294
|
+
*/
|
|
295
|
+
declare function RootTalePreviewNotice({ locale, message, expiresAt, }: RootTalePreviewNoticeProps): ReactElement;
|
|
296
|
+
|
|
273
297
|
type RootTalePageProps = {
|
|
274
298
|
apiKey: string;
|
|
275
299
|
slugOrId: string;
|
|
@@ -332,4 +356,4 @@ type PostBodySource = {
|
|
|
332
356
|
*/
|
|
333
357
|
declare function resolvePostBodySource(bodyHtml: string | null | undefined): PostBodySource;
|
|
334
358
|
|
|
335
|
-
export { type BlogPostBreadcrumbOptions, type CtaButton, type CtaButtonType, type FloatingCtaPosition, type LeadFormVertical, type PostBodySource, RenderTiptap, RootTaleBlogCategories, type RootTaleBlogCategoriesProps, RootTaleBlogList, type RootTaleBlogListProps, RootTaleBlogPost, type RootTaleBlogPostProps, type RootTaleCssVars, RootTaleExposureSlot, type RootTaleExposureSlotProps, RootTaleFaqJsonLd, RootTaleFloatingCta, type RootTaleFloatingCtaProps, RootTaleLeadForm, type RootTaleLeadFormProps, RootTalePage, type RootTalePageProps, RootTalePostCard, type RootTalePostCardProps, RootTaleTableOfContents, type RootTaleTableOfContentsProps, type RootTaleThemeInput, RootTaleThemeProvider, type TocEntry, attachHeadingIds, extractToc, headingToId, renderBlock, renderBlocks, renderBoundBlocks, resolvePostBodySource, themeToCssVars };
|
|
359
|
+
export { type BlogPostBreadcrumbOptions, type CtaButton, type CtaButtonType, type FloatingCtaPosition, type LeadFormVertical, type PostBodySource, RenderTiptap, RootTaleBlogCategories, type RootTaleBlogCategoriesProps, RootTaleBlogList, type RootTaleBlogListProps, RootTaleBlogPost, type RootTaleBlogPostProps, type RootTaleCssVars, RootTaleExposureSlot, type RootTaleExposureSlotProps, RootTaleFaqJsonLd, RootTaleFloatingCta, type RootTaleFloatingCtaProps, RootTaleLeadForm, type RootTaleLeadFormProps, RootTalePage, type RootTalePageProps, RootTalePostCard, type RootTalePostCardProps, RootTalePreviewNotice, type RootTalePreviewNoticeProps, RootTaleTableOfContents, type RootTaleTableOfContentsProps, type RootTaleThemeInput, RootTaleThemeProvider, type TocEntry, attachHeadingIds, extractToc, headingToId, renderBlock, renderBlocks, renderBoundBlocks, resolvePostBodySource, themeToCssVars };
|
package/dist/server.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
defaultCategoryHref,
|
|
6
6
|
filterPostsByCategory,
|
|
7
7
|
trimSlash
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-FJANIAZN.js";
|
|
9
9
|
import {
|
|
10
10
|
getSectionNodeRenderer
|
|
11
11
|
} from "./chunk-KSPPYX22.js";
|
|
@@ -84,6 +84,8 @@ var DICTS = {
|
|
|
84
84
|
relatedPostsTitle: "\uAD00\uB828 \uAE00",
|
|
85
85
|
postNotFound: "\uAE00\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
86
86
|
pageNotFound: "\uD398\uC774\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
87
|
+
previewExpired: "\uBBF8\uB9AC\uBCF4\uAE30 \uB9C1\uD06C\uAC00 \uB9CC\uB8CC\uB410\uC5B4\uC694. \uAD00\uB9AC\uC790 \uD3B8\uC9D1\uAE30\uC5D0\uC11C \uBBF8\uB9AC\uBCF4\uAE30\uB97C \uB2E4\uC2DC \uC5F4\uC5B4 \uC8FC\uC138\uC694.",
|
|
88
|
+
previewNotice: "\uBBF8\uB9AC\uBCF4\uAE30 \u2014 \uC544\uC9C1 \uACF5\uAC1C\uB418\uC9C0 \uC54A\uC740 \uB0B4\uC6A9\uC774\uBA70 \uAC80\uC0C9\uC5D0 \uB178\uCD9C\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.",
|
|
87
89
|
tableOfContentsTitle: "\uBAA9\uCC28"
|
|
88
90
|
},
|
|
89
91
|
en: {
|
|
@@ -93,6 +95,8 @@ var DICTS = {
|
|
|
93
95
|
relatedPostsTitle: "Related posts",
|
|
94
96
|
postNotFound: "Post not found.",
|
|
95
97
|
pageNotFound: "Page not found.",
|
|
98
|
+
previewExpired: "This preview link has expired. Open the preview again from the admin editor.",
|
|
99
|
+
previewNotice: "Preview \u2014 this content is not public and is hidden from search engines.",
|
|
96
100
|
tableOfContentsTitle: "Table of contents"
|
|
97
101
|
}
|
|
98
102
|
};
|
|
@@ -850,7 +854,9 @@ async function RootTaleBlogCategories(props) {
|
|
|
850
854
|
// src/server/blog-post.tsx
|
|
851
855
|
import {
|
|
852
856
|
fetchPost,
|
|
857
|
+
fetchPostPreview,
|
|
853
858
|
fetchPosts as fetchPosts2,
|
|
859
|
+
isPreviewExpiredError,
|
|
854
860
|
resolvePostDisplay as resolvePostDisplay2,
|
|
855
861
|
selectRelatedPosts
|
|
856
862
|
} from "@roottale/cms-client/server";
|
|
@@ -1538,10 +1544,35 @@ function authorImageRadiusCss(radius) {
|
|
|
1538
1544
|
if (radius === "rounded") return "0.875rem";
|
|
1539
1545
|
return "0";
|
|
1540
1546
|
}
|
|
1547
|
+
async function lookupPost(input) {
|
|
1548
|
+
if (input.previewToken) {
|
|
1549
|
+
try {
|
|
1550
|
+
const preview = await fetchPostPreview({
|
|
1551
|
+
apiKey: input.apiKey,
|
|
1552
|
+
baseUrl: input.baseUrl,
|
|
1553
|
+
token: input.previewToken
|
|
1554
|
+
});
|
|
1555
|
+
return preview ? { kind: "post", post: preview } : { kind: "missing" };
|
|
1556
|
+
} catch (error) {
|
|
1557
|
+
if (isPreviewExpiredError(error)) return { kind: "preview-expired" };
|
|
1558
|
+
throw error;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
if (!input.slugOrId) return { kind: "missing" };
|
|
1562
|
+
const post = await fetchPost({
|
|
1563
|
+
apiKey: input.apiKey,
|
|
1564
|
+
slugOrId: input.slugOrId,
|
|
1565
|
+
baseUrl: input.baseUrl,
|
|
1566
|
+
...input.locale ? { locale: input.locale } : {}
|
|
1567
|
+
});
|
|
1568
|
+
return post ? { kind: "post", post } : { kind: "missing" };
|
|
1569
|
+
}
|
|
1541
1570
|
async function RootTaleBlogPost(props) {
|
|
1542
1571
|
const {
|
|
1543
1572
|
apiKey,
|
|
1544
1573
|
slugOrId,
|
|
1574
|
+
previewToken,
|
|
1575
|
+
previewExpiredElement,
|
|
1545
1576
|
baseUrl,
|
|
1546
1577
|
notFoundElement,
|
|
1547
1578
|
showTitle = true,
|
|
@@ -1556,14 +1587,18 @@ async function RootTaleBlogPost(props) {
|
|
|
1556
1587
|
authorHref = defaultAuthorHref,
|
|
1557
1588
|
breadcrumb
|
|
1558
1589
|
} = props;
|
|
1559
|
-
const [
|
|
1560
|
-
|
|
1590
|
+
const [lookup, themeStyle, blogSettings] = await Promise.all([
|
|
1591
|
+
lookupPost({ apiKey, baseUrl, slugOrId, previewToken, locale }),
|
|
1561
1592
|
resolveThemeStyleFailSoft({ themeProp, apiKey, baseUrl }),
|
|
1562
1593
|
fetchBlogSettingsFailSoft({ apiKey, baseUrl })
|
|
1563
1594
|
]);
|
|
1564
|
-
if (
|
|
1595
|
+
if (lookup.kind === "preview-expired") {
|
|
1596
|
+
return previewExpiredElement ?? /* @__PURE__ */ jsx17("div", { "data-roottale-cms": "post-preview-expired", style: themeStyle ?? void 0, children: /* @__PURE__ */ jsx17("p", { className: "rt-cms-empty", children: t(locale, "previewExpired") }) });
|
|
1597
|
+
}
|
|
1598
|
+
if (lookup.kind === "missing") {
|
|
1565
1599
|
return notFoundElement ?? /* @__PURE__ */ jsx17("div", { "data-roottale-cms": "post-missing", style: themeStyle ?? void 0, children: /* @__PURE__ */ jsx17("p", { className: "rt-cms-empty", children: t(locale, "postNotFound") }) });
|
|
1566
1600
|
}
|
|
1601
|
+
const post = lookup.post;
|
|
1567
1602
|
const display = resolvePostDisplay2(post, blogSettings, {
|
|
1568
1603
|
showTableOfContents,
|
|
1569
1604
|
tableOfContentsTitle
|
|
@@ -1703,9 +1738,32 @@ async function RootTaleBlogPost(props) {
|
|
|
1703
1738
|
);
|
|
1704
1739
|
}
|
|
1705
1740
|
|
|
1741
|
+
// src/server/preview-notice.tsx
|
|
1742
|
+
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1743
|
+
function formatExpiry(locale, iso) {
|
|
1744
|
+
const date = new Date(iso);
|
|
1745
|
+
if (Number.isNaN(date.getTime())) return null;
|
|
1746
|
+
const time = new Intl.DateTimeFormat(locale === "en" ? "en-US" : "ko-KR", {
|
|
1747
|
+
hour: "2-digit",
|
|
1748
|
+
minute: "2-digit"
|
|
1749
|
+
}).format(date);
|
|
1750
|
+
return locale === "en" ? `Valid until ${time}.` : `${time}\uAE4C\uC9C0 \uBCFC \uC218 \uC788\uC5B4\uC694.`;
|
|
1751
|
+
}
|
|
1752
|
+
function RootTalePreviewNotice({
|
|
1753
|
+
locale,
|
|
1754
|
+
message,
|
|
1755
|
+
expiresAt
|
|
1756
|
+
}) {
|
|
1757
|
+
const expiry = expiresAt ? formatExpiry(locale, expiresAt) : null;
|
|
1758
|
+
return /* @__PURE__ */ jsxs14("div", { "data-roottale-cms": "preview-notice", className: "rt-cms-preview-notice", role: "status", children: [
|
|
1759
|
+
/* @__PURE__ */ jsx18("span", { children: message ?? t(locale, "previewNotice") }),
|
|
1760
|
+
expiry ? /* @__PURE__ */ jsx18("span", { className: "rt-cms-preview-notice__expiry", children: expiry }) : null
|
|
1761
|
+
] });
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1706
1764
|
// src/server/page.tsx
|
|
1707
1765
|
import { fetchPost as fetchPost2 } from "@roottale/cms-client/server";
|
|
1708
|
-
import { jsx as
|
|
1766
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1709
1767
|
async function RootTalePage(props) {
|
|
1710
1768
|
const {
|
|
1711
1769
|
apiKey,
|
|
@@ -1722,19 +1780,19 @@ async function RootTalePage(props) {
|
|
|
1722
1780
|
resolveThemeStyleFailSoft({ themeProp, apiKey, baseUrl })
|
|
1723
1781
|
]);
|
|
1724
1782
|
if (!post) {
|
|
1725
|
-
return notFoundElement ?? /* @__PURE__ */
|
|
1783
|
+
return notFoundElement ?? /* @__PURE__ */ jsx19("div", { "data-roottale-cms": "page-missing", style: themeStyle ?? void 0, children: /* @__PURE__ */ jsx19("p", { className: "rt-cms-empty", children: t(locale, "pageNotFound") }) });
|
|
1726
1784
|
}
|
|
1727
1785
|
const pageBodySource = resolvePostBodySource(post.bodyHtml);
|
|
1728
1786
|
const bodyJson = pageBodySource.kind === "json" && prepareBody ? await prepareBody(post.bodyJson) : post.bodyJson;
|
|
1729
|
-
return /* @__PURE__ */
|
|
1787
|
+
return /* @__PURE__ */ jsxs15(
|
|
1730
1788
|
"article",
|
|
1731
1789
|
{
|
|
1732
1790
|
"data-roottale-cms": "page",
|
|
1733
1791
|
className: "rt-cms-article",
|
|
1734
1792
|
style: themeStyle ?? void 0,
|
|
1735
1793
|
children: [
|
|
1736
|
-
showTitle ? /* @__PURE__ */
|
|
1737
|
-
/* @__PURE__ */
|
|
1794
|
+
showTitle ? /* @__PURE__ */ jsx19("header", { className: "rt-cms-post-header", children: /* @__PURE__ */ jsx19("h1", { className: "rt-cms-title", children: post.title }) }) : null,
|
|
1795
|
+
/* @__PURE__ */ jsx19("div", { "data-roottale-cms": "body", className: "rt-cms-body", children: pageBodySource.kind === "html" ? /* @__PURE__ */ jsx19("div", { dangerouslySetInnerHTML: { __html: pageBodySource.html } }) : /* @__PURE__ */ jsx19(
|
|
1738
1796
|
RenderTiptap,
|
|
1739
1797
|
{
|
|
1740
1798
|
doc: bodyJson,
|
|
@@ -1750,7 +1808,7 @@ async function RootTalePage(props) {
|
|
|
1750
1808
|
|
|
1751
1809
|
// src/server/exposure-slot.tsx
|
|
1752
1810
|
import { fetchExposure } from "@roottale/cms-client/server";
|
|
1753
|
-
import { jsx as
|
|
1811
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1754
1812
|
async function RootTaleExposureSlot(props) {
|
|
1755
1813
|
const campaign = await fetchExposure({
|
|
1756
1814
|
apiKey: props.apiKey,
|
|
@@ -1761,7 +1819,7 @@ async function RootTaleExposureSlot(props) {
|
|
|
1761
1819
|
revalidate: props.revalidate
|
|
1762
1820
|
});
|
|
1763
1821
|
if (!campaign || !props.allowedVariants.includes(campaign.content.variant)) return null;
|
|
1764
|
-
return /* @__PURE__ */
|
|
1822
|
+
return /* @__PURE__ */ jsx20(RootTaleExposure, { campaign, allowedVariants: props.allowedVariants });
|
|
1765
1823
|
}
|
|
1766
1824
|
export {
|
|
1767
1825
|
RenderTiptap,
|
|
@@ -1774,6 +1832,7 @@ export {
|
|
|
1774
1832
|
RootTaleLeadForm,
|
|
1775
1833
|
RootTalePage,
|
|
1776
1834
|
RootTalePostCard,
|
|
1835
|
+
RootTalePreviewNotice,
|
|
1777
1836
|
RootTaleTableOfContents,
|
|
1778
1837
|
RootTaleThemeProvider,
|
|
1779
1838
|
attachHeadingIds,
|