@roottale/cms-renderer-next 0.53.0 → 0.53.1
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 +17 -0
- package/README.md +10 -2
- package/dist/chunk-GVKENK6H.js +75 -0
- package/dist/chunk-GVKENK6H.js.map +1 -0
- package/dist/cms-public.css +27 -0
- package/dist/exposure-client.d.ts +9 -0
- package/dist/exposure-client.js +8 -0
- package/dist/exposure-client.js.map +1 -0
- package/dist/routes.d.ts +1 -1
- package/dist/routes.js +19 -12
- package/dist/routes.js.map +1 -1
- package/dist/server.d.ts +45 -1
- package/dist/server.js +106 -21
- package/dist/server.js.map +1 -1
- package/package.json +4 -4
package/dist/server.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ 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
6
|
export { a as BlogCategory, B as BlogCategoryWithCount, c as collectCategories, b as collectCategoriesWithCounts, d as defaultCategoryHref, f as filterPostsByCategory } from './blog-filter-BKCGM0qd.js';
|
|
7
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* `<RootTalePostCard>` — server-only summary card for a single CmsPostContent.
|
|
@@ -277,9 +278,23 @@ type RootTalePageProps = {
|
|
|
277
278
|
showTitle?: boolean;
|
|
278
279
|
theme?: RootTaleThemeInput;
|
|
279
280
|
locale?: string;
|
|
281
|
+
/** 페이지 JSON을 렌더하기 직전 콘텐츠 참조를 실제 섹션 props로 바꾸는 서버 함수. */
|
|
282
|
+
prepareBody?: (document: Record<string, unknown>) => Promise<Record<string, unknown>>;
|
|
280
283
|
};
|
|
281
284
|
declare function RootTalePage(props: RootTalePageProps): Promise<ReactElement>;
|
|
282
285
|
|
|
286
|
+
interface RootTaleExposureSlotProps {
|
|
287
|
+
readonly apiKey: string;
|
|
288
|
+
readonly baseUrl?: string;
|
|
289
|
+
readonly siteId?: string;
|
|
290
|
+
readonly slotKey: string;
|
|
291
|
+
readonly path: string;
|
|
292
|
+
readonly allowedVariants: readonly string[];
|
|
293
|
+
readonly revalidate?: number;
|
|
294
|
+
}
|
|
295
|
+
/** FRONT가 코드로 만든 슬롯 안에서만 활성 배너·팝업을 렌더한다. */
|
|
296
|
+
declare function RootTaleExposureSlot(props: RootTaleExposureSlotProps): Promise<react_jsx_runtime.JSX.Element | null>;
|
|
297
|
+
|
|
283
298
|
type RenderTiptapProps = {
|
|
284
299
|
readonly doc: Record<string, unknown>;
|
|
285
300
|
readonly fields?: Record<string, unknown> | null;
|
|
@@ -288,4 +303,33 @@ type RenderTiptapProps = {
|
|
|
288
303
|
};
|
|
289
304
|
declare function RenderTiptap({ doc, fields, apiKey, baseUrl, }: RenderTiptapProps): ReactElement;
|
|
290
305
|
|
|
291
|
-
|
|
306
|
+
/**
|
|
307
|
+
* 본문 렌더 소스 결정 — HTML 정본 우선, 없으면 Block JSON 폴백.
|
|
308
|
+
*
|
|
309
|
+
* 배경: 외부에서 이관한 글은 **HTML 이 정본**이고 body_json 은 그 파생/대체본이다.
|
|
310
|
+
* 파생본은 표·중첩 목록 같은 구조에서 원문과 미묘하게 달라질 수 있으므로, 원문이
|
|
311
|
+
* 남아 있으면 그것을 보여주는 편이 정확하다. 반대로 에디터에서 편집된 글은
|
|
312
|
+
* body_html 이 비워지므로(저장 경로가 무효화) 자동으로 JSON 경로로 돌아온다.
|
|
313
|
+
*
|
|
314
|
+
* 안전성: HTML 은 신뢰하지 않는다. 최종 sink 는 공용 `sanitizeHtml` 하나뿐이며
|
|
315
|
+
* (cms-core), 렌더 직전 여기서 통과시킨다 — 저장 시점에 정제됐더라도 다시 한다
|
|
316
|
+
* (저장 경로가 여럿이고 sanitizer 규칙은 갱신되므로, 방어는 렌더 시점 기준).
|
|
317
|
+
*
|
|
318
|
+
* sanitize 결과가 실질적으로 비면(태그만 남고 내용이 없음) HTML 을 쓰지 않고
|
|
319
|
+
* JSON 으로 폴백한다 — 빈 화면보다 파생본이 낫다.
|
|
320
|
+
*/
|
|
321
|
+
type PostBodySource = {
|
|
322
|
+
readonly kind: "html";
|
|
323
|
+
readonly html: string;
|
|
324
|
+
} | {
|
|
325
|
+
readonly kind: "json";
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* 렌더에 쓸 본문 소스를 고른다.
|
|
329
|
+
*
|
|
330
|
+
* @param bodyHtml 원문 HTML 정본 (null/미포함 = 구 서버이거나 JSON 이 정본).
|
|
331
|
+
* @returns `kind: "html"` 이면 `html` 은 **이미 sanitize 된** 값이라 그대로 주입 가능.
|
|
332
|
+
*/
|
|
333
|
+
declare function resolvePostBodySource(bodyHtml: string | null | undefined): PostBodySource;
|
|
334
|
+
|
|
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 };
|
package/dist/server.js
CHANGED
|
@@ -12,6 +12,9 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
LeadFormMeta
|
|
14
14
|
} from "./chunk-VG6UUF4D.js";
|
|
15
|
+
import {
|
|
16
|
+
RootTaleExposure
|
|
17
|
+
} from "./chunk-GVKENK6H.js";
|
|
15
18
|
|
|
16
19
|
// src/PostCard.tsx
|
|
17
20
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -623,7 +626,6 @@ function attachHeadingIds(doc, entries) {
|
|
|
623
626
|
|
|
624
627
|
// src/server/blog-list.tsx
|
|
625
628
|
import {
|
|
626
|
-
fetchPosts,
|
|
627
629
|
resolvePostDisplay
|
|
628
630
|
} from "@roottale/cms-client/server";
|
|
629
631
|
import {
|
|
@@ -640,6 +642,18 @@ async function fetchBlogSettingsFailSoft(input) {
|
|
|
640
642
|
return fetchBlogSettings(input).catch(() => DEFAULT_BLOG_SETTINGS);
|
|
641
643
|
}
|
|
642
644
|
|
|
645
|
+
// src/server/fetch-posts-fail-soft.ts
|
|
646
|
+
import {
|
|
647
|
+
fetchPosts
|
|
648
|
+
} from "@roottale/cms-client/server";
|
|
649
|
+
async function fetchPostsFailSoft(options) {
|
|
650
|
+
try {
|
|
651
|
+
return await fetchPosts(options);
|
|
652
|
+
} catch {
|
|
653
|
+
return { items: [], hasMore: false, nextCursor: null };
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
643
657
|
// src/server/post-links.ts
|
|
644
658
|
import {
|
|
645
659
|
resolvePostCollection,
|
|
@@ -726,7 +740,7 @@ async function RootTaleBlogList(props) {
|
|
|
726
740
|
} = props;
|
|
727
741
|
const postHref = props.postHref ?? (collections ? makeCollectionPostHref(collections) : defaultPostHref);
|
|
728
742
|
const [page, themeStyle, blogSettings] = await Promise.all([
|
|
729
|
-
|
|
743
|
+
fetchPostsFailSoft({
|
|
730
744
|
apiKey,
|
|
731
745
|
baseUrl,
|
|
732
746
|
limit,
|
|
@@ -787,9 +801,6 @@ async function RootTaleBlogList(props) {
|
|
|
787
801
|
}
|
|
788
802
|
|
|
789
803
|
// src/server/blog-categories.tsx
|
|
790
|
-
import {
|
|
791
|
-
fetchPosts as fetchPosts2
|
|
792
|
-
} from "@roottale/cms-client/server";
|
|
793
804
|
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
794
805
|
async function RootTaleBlogCategories(props) {
|
|
795
806
|
const {
|
|
@@ -804,7 +815,7 @@ async function RootTaleBlogCategories(props) {
|
|
|
804
815
|
theme: themeProp
|
|
805
816
|
} = props;
|
|
806
817
|
const [page, themeStyle] = await Promise.all([
|
|
807
|
-
|
|
818
|
+
fetchPostsFailSoft({
|
|
808
819
|
apiKey,
|
|
809
820
|
baseUrl,
|
|
810
821
|
limit,
|
|
@@ -839,7 +850,7 @@ async function RootTaleBlogCategories(props) {
|
|
|
839
850
|
// src/server/blog-post.tsx
|
|
840
851
|
import {
|
|
841
852
|
fetchPost,
|
|
842
|
-
fetchPosts as
|
|
853
|
+
fetchPosts as fetchPosts2,
|
|
843
854
|
resolvePostDisplay as resolvePostDisplay2,
|
|
844
855
|
selectRelatedPosts
|
|
845
856
|
} from "@roottale/cms-client/server";
|
|
@@ -931,12 +942,30 @@ function renderFieldFacts(post) {
|
|
|
931
942
|
] }, meta.name)) }) });
|
|
932
943
|
}
|
|
933
944
|
|
|
945
|
+
// src/server/post-body-source.ts
|
|
946
|
+
import { sanitizeHtml as sanitizeHtml2 } from "@roottale/cms-core";
|
|
947
|
+
function hasVisibleContent(html) {
|
|
948
|
+
if (/<(?:img|hr|br|iframe|video|audio)\b/i.test(html)) return true;
|
|
949
|
+
return html.replace(/<[^>]*>/g, "").replace(/ /gi, " ").trim().length > 0;
|
|
950
|
+
}
|
|
951
|
+
function resolvePostBodySource(bodyHtml) {
|
|
952
|
+
if (typeof bodyHtml !== "string") return { kind: "json" };
|
|
953
|
+
const trimmed = bodyHtml.trim();
|
|
954
|
+
if (trimmed.length === 0) return { kind: "json" };
|
|
955
|
+
const sanitized = sanitizeHtml2(trimmed);
|
|
956
|
+
if (!hasVisibleContent(sanitized)) return { kind: "json" };
|
|
957
|
+
return { kind: "html", html: sanitized };
|
|
958
|
+
}
|
|
959
|
+
|
|
934
960
|
// src/server/tiptap-node-renderer.tsx
|
|
961
|
+
import { Fragment as Fragment4 } from "react";
|
|
935
962
|
import {
|
|
936
963
|
bindingSrcValue,
|
|
937
964
|
bindingTextValue,
|
|
938
965
|
boundFieldValue,
|
|
939
|
-
|
|
966
|
+
ensureImportedHtmlDocumentRoots,
|
|
967
|
+
normalizeImageAlt,
|
|
968
|
+
scopeImportedCss
|
|
940
969
|
} from "@roottale/cms-core";
|
|
941
970
|
|
|
942
971
|
// src/server/tiptap-embed-renderer.tsx
|
|
@@ -1151,6 +1180,33 @@ function renderTiptapNode(value, key, context) {
|
|
|
1151
1180
|
key
|
|
1152
1181
|
);
|
|
1153
1182
|
}
|
|
1183
|
+
case "importedHtml": {
|
|
1184
|
+
const rawHtml = node.attrs?.html;
|
|
1185
|
+
if (typeof rawHtml !== "string" || rawHtml.length === 0) return null;
|
|
1186
|
+
const scope = typeof node.attrs?.scope === "string" ? node.attrs.scope : "";
|
|
1187
|
+
const assetUrls = Array.isArray(node.attrs?.assetUrls) ? node.attrs.assetUrls.filter(
|
|
1188
|
+
(value2) => typeof value2 === "string" && /^https:\/\//i.test(value2)
|
|
1189
|
+
) : [];
|
|
1190
|
+
const scopedCss = scopeImportedCss(
|
|
1191
|
+
typeof node.attrs?.css === "string" ? node.attrs.css : "",
|
|
1192
|
+
scope,
|
|
1193
|
+
assetUrls
|
|
1194
|
+
);
|
|
1195
|
+
return /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
1196
|
+
scopedCss ? /* @__PURE__ */ jsx12("style", { "data-rt-imported-style": scope, children: scopedCss }) : null,
|
|
1197
|
+
/* @__PURE__ */ jsx12(
|
|
1198
|
+
"div",
|
|
1199
|
+
{
|
|
1200
|
+
className: "rt-imported-html",
|
|
1201
|
+
"data-rt-import-scope": scopedCss ? scope : void 0,
|
|
1202
|
+
style: { position: "relative", isolation: "isolate" },
|
|
1203
|
+
dangerouslySetInnerHTML: {
|
|
1204
|
+
__html: ensureImportedHtmlDocumentRoots(rawHtml, assetUrls)
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
)
|
|
1208
|
+
] }, key);
|
|
1209
|
+
}
|
|
1154
1210
|
case "columns":
|
|
1155
1211
|
return /* @__PURE__ */ jsx12("div", { className: "rt-columns", children }, key);
|
|
1156
1212
|
case "column":
|
|
@@ -1217,7 +1273,7 @@ function renderTiptapNode(value, key, context) {
|
|
|
1217
1273
|
}
|
|
1218
1274
|
|
|
1219
1275
|
// src/server/render-tiptap.tsx
|
|
1220
|
-
import { Fragment as
|
|
1276
|
+
import { Fragment as Fragment5, jsx as jsx13 } from "react/jsx-runtime";
|
|
1221
1277
|
function isDevelopmentRuntime() {
|
|
1222
1278
|
const processValue = Reflect.get(globalThis, "process");
|
|
1223
1279
|
if (!isRecord(processValue)) return true;
|
|
@@ -1252,7 +1308,7 @@ function RenderTiptap({
|
|
|
1252
1308
|
fields: fields ?? null,
|
|
1253
1309
|
section: createSectionContextWithBlogListNetworkFetch(apiKey, baseUrl)
|
|
1254
1310
|
};
|
|
1255
|
-
return /* @__PURE__ */ jsx13(
|
|
1311
|
+
return /* @__PURE__ */ jsx13(Fragment5, { children: contentNodes(renderDoc).map((value, index) => {
|
|
1256
1312
|
const node = parseTiptapNode(value);
|
|
1257
1313
|
if (node?.type !== "tableOfContents") {
|
|
1258
1314
|
return renderTiptapNode(value, index, context);
|
|
@@ -1270,7 +1326,7 @@ function RenderTiptap({
|
|
|
1270
1326
|
}
|
|
1271
1327
|
|
|
1272
1328
|
// src/server/blog-post-body.tsx
|
|
1273
|
-
import { Fragment as
|
|
1329
|
+
import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1274
1330
|
function BlogPostBody(props) {
|
|
1275
1331
|
const {
|
|
1276
1332
|
doc,
|
|
@@ -1279,10 +1335,17 @@ function BlogPostBody(props) {
|
|
|
1279
1335
|
baseUrl,
|
|
1280
1336
|
toc,
|
|
1281
1337
|
tocTitle,
|
|
1282
|
-
tocPosition
|
|
1338
|
+
tocPosition,
|
|
1339
|
+
bodyHtml
|
|
1283
1340
|
} = props;
|
|
1284
1341
|
const tableOfContents = toc.length > 0 ? /* @__PURE__ */ jsx14(RootTaleTableOfContents, { entries: toc, title: tocTitle }) : null;
|
|
1285
|
-
const
|
|
1342
|
+
const source = resolvePostBodySource(bodyHtml);
|
|
1343
|
+
const body = /* @__PURE__ */ jsx14("div", { "data-roottale-cms": "body", className: "rt-cms-body", children: source.kind === "html" ? (
|
|
1344
|
+
// source.html 은 resolvePostBodySource 가 공용 sanitizeHtml 로 정제한 값이다
|
|
1345
|
+
// (이 컴포넌트에서 한 번 더 정제하지 않는 이유 — sink 가 한 곳이어야 눈으로
|
|
1346
|
+
// 추적 가능하고, 이중 정제는 안전을 더 만들지 않으면서 비용만 든다).
|
|
1347
|
+
/* @__PURE__ */ jsx14("div", { dangerouslySetInnerHTML: { __html: source.html } })
|
|
1348
|
+
) : /* @__PURE__ */ jsx14(
|
|
1286
1349
|
RenderTiptap,
|
|
1287
1350
|
{
|
|
1288
1351
|
doc,
|
|
@@ -1297,7 +1360,7 @@ function BlogPostBody(props) {
|
|
|
1297
1360
|
/* @__PURE__ */ jsx14("aside", { className: "rt-cms-toc-side", children: tableOfContents })
|
|
1298
1361
|
] });
|
|
1299
1362
|
}
|
|
1300
|
-
return /* @__PURE__ */ jsxs10(
|
|
1363
|
+
return /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
1301
1364
|
tableOfContents,
|
|
1302
1365
|
body
|
|
1303
1366
|
] });
|
|
@@ -1311,7 +1374,7 @@ import {
|
|
|
1311
1374
|
import {
|
|
1312
1375
|
resolvePostCollection as resolvePostCollection2
|
|
1313
1376
|
} from "@roottale/cms-core";
|
|
1314
|
-
import { Fragment as
|
|
1377
|
+
import { Fragment as Fragment7, jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1315
1378
|
function absoluteUrl(siteUrl, path) {
|
|
1316
1379
|
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
1317
1380
|
return `${trimSlash(siteUrl)}${normalizedPath}`;
|
|
@@ -1346,7 +1409,7 @@ function renderBlogPostBreadcrumb(input) {
|
|
|
1346
1409
|
url: absoluteUrl(siteUrl, crumb.href)
|
|
1347
1410
|
}))
|
|
1348
1411
|
) : null;
|
|
1349
|
-
return /* @__PURE__ */ jsxs11(
|
|
1412
|
+
return /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
1350
1413
|
/* @__PURE__ */ jsx15("nav", { "aria-label": "\uBE0C\uB808\uB4DC\uD06C\uB7FC", className: "rt-cms-breadcrumb", children: /* @__PURE__ */ jsx15("ol", { children: crumbs.map(
|
|
1351
1414
|
(crumb, index) => index === crumbs.length - 1 ? /* @__PURE__ */ jsx15("li", { "aria-current": "page", children: crumb.label }, index) : /* @__PURE__ */ jsx15("li", { children: /* @__PURE__ */ jsx15("a", { href: crumb.href, children: crumb.label }) }, index)
|
|
1352
1415
|
) }) }),
|
|
@@ -1426,7 +1489,7 @@ function RootTaleFaqJsonLd({
|
|
|
1426
1489
|
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1427
1490
|
async function fetchRelatedPostsFailSoft(input) {
|
|
1428
1491
|
if (input.count <= 0) return [];
|
|
1429
|
-
const candidates = await
|
|
1492
|
+
const candidates = await fetchPosts2({
|
|
1430
1493
|
apiKey: input.apiKey,
|
|
1431
1494
|
baseUrl: input.baseUrl,
|
|
1432
1495
|
type: "post",
|
|
@@ -1611,7 +1674,8 @@ async function RootTaleBlogPost(props) {
|
|
|
1611
1674
|
baseUrl,
|
|
1612
1675
|
toc,
|
|
1613
1676
|
tocTitle: display.tocTitle,
|
|
1614
|
-
tocPosition: display.tocPosition
|
|
1677
|
+
tocPosition: display.tocPosition,
|
|
1678
|
+
bodyHtml: post.bodyHtml
|
|
1615
1679
|
}
|
|
1616
1680
|
),
|
|
1617
1681
|
showAuthorCard && authorName ? /* @__PURE__ */ jsxs13("section", { className: "rt-cms-author-card", "aria-label": "\uC791\uC131\uC790", children: [
|
|
@@ -1650,7 +1714,8 @@ async function RootTalePage(props) {
|
|
|
1650
1714
|
notFoundElement,
|
|
1651
1715
|
showTitle = true,
|
|
1652
1716
|
theme: themeProp,
|
|
1653
|
-
locale
|
|
1717
|
+
locale,
|
|
1718
|
+
prepareBody
|
|
1654
1719
|
} = props;
|
|
1655
1720
|
const [post, themeStyle] = await Promise.all([
|
|
1656
1721
|
fetchPost2({ apiKey, slugOrId, baseUrl, ...locale ? { locale } : {} }),
|
|
@@ -1659,6 +1724,8 @@ async function RootTalePage(props) {
|
|
|
1659
1724
|
if (!post) {
|
|
1660
1725
|
return notFoundElement ?? /* @__PURE__ */ jsx18("div", { "data-roottale-cms": "page-missing", style: themeStyle ?? void 0, children: /* @__PURE__ */ jsx18("p", { className: "rt-cms-empty", children: t(locale, "pageNotFound") }) });
|
|
1661
1726
|
}
|
|
1727
|
+
const pageBodySource = resolvePostBodySource(post.bodyHtml);
|
|
1728
|
+
const bodyJson = pageBodySource.kind === "json" && prepareBody ? await prepareBody(post.bodyJson) : post.bodyJson;
|
|
1662
1729
|
return /* @__PURE__ */ jsxs14(
|
|
1663
1730
|
"article",
|
|
1664
1731
|
{
|
|
@@ -1667,10 +1734,10 @@ async function RootTalePage(props) {
|
|
|
1667
1734
|
style: themeStyle ?? void 0,
|
|
1668
1735
|
children: [
|
|
1669
1736
|
showTitle ? /* @__PURE__ */ jsx18("header", { className: "rt-cms-post-header", children: /* @__PURE__ */ jsx18("h1", { className: "rt-cms-title", children: post.title }) }) : null,
|
|
1670
|
-
/* @__PURE__ */ jsx18("div", { "data-roottale-cms": "body", className: "rt-cms-body", children: /* @__PURE__ */ jsx18(
|
|
1737
|
+
/* @__PURE__ */ jsx18("div", { "data-roottale-cms": "body", className: "rt-cms-body", children: pageBodySource.kind === "html" ? /* @__PURE__ */ jsx18("div", { dangerouslySetInnerHTML: { __html: pageBodySource.html } }) : /* @__PURE__ */ jsx18(
|
|
1671
1738
|
RenderTiptap,
|
|
1672
1739
|
{
|
|
1673
|
-
doc:
|
|
1740
|
+
doc: bodyJson,
|
|
1674
1741
|
fields: post.fields,
|
|
1675
1742
|
apiKey,
|
|
1676
1743
|
baseUrl
|
|
@@ -1680,11 +1747,28 @@ async function RootTalePage(props) {
|
|
|
1680
1747
|
}
|
|
1681
1748
|
);
|
|
1682
1749
|
}
|
|
1750
|
+
|
|
1751
|
+
// src/server/exposure-slot.tsx
|
|
1752
|
+
import { fetchExposure } from "@roottale/cms-client/server";
|
|
1753
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1754
|
+
async function RootTaleExposureSlot(props) {
|
|
1755
|
+
const campaign = await fetchExposure({
|
|
1756
|
+
apiKey: props.apiKey,
|
|
1757
|
+
baseUrl: props.baseUrl,
|
|
1758
|
+
siteId: props.siteId,
|
|
1759
|
+
slotKey: props.slotKey,
|
|
1760
|
+
path: props.path,
|
|
1761
|
+
revalidate: props.revalidate
|
|
1762
|
+
});
|
|
1763
|
+
if (!campaign || !props.allowedVariants.includes(campaign.content.variant)) return null;
|
|
1764
|
+
return /* @__PURE__ */ jsx19(RootTaleExposure, { campaign, allowedVariants: props.allowedVariants });
|
|
1765
|
+
}
|
|
1683
1766
|
export {
|
|
1684
1767
|
RenderTiptap,
|
|
1685
1768
|
RootTaleBlogCategories,
|
|
1686
1769
|
RootTaleBlogList,
|
|
1687
1770
|
RootTaleBlogPost,
|
|
1771
|
+
RootTaleExposureSlot,
|
|
1688
1772
|
RootTaleFaqJsonLd,
|
|
1689
1773
|
RootTaleFloatingCta,
|
|
1690
1774
|
RootTaleLeadForm,
|
|
@@ -1702,6 +1786,7 @@ export {
|
|
|
1702
1786
|
renderBlock,
|
|
1703
1787
|
renderBlocks,
|
|
1704
1788
|
renderBoundBlocks,
|
|
1789
|
+
resolvePostBodySource,
|
|
1705
1790
|
themeToCssVars2 as themeToCssVars
|
|
1706
1791
|
};
|
|
1707
1792
|
//# sourceMappingURL=server.js.map
|