@roottale/cms-client 0.53.0 → 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 CHANGED
@@ -1,5 +1,44 @@
1
1
  # @roottale/cms-client
2
2
 
3
+ ## 0.55.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6cb9dd5: 공개 글 응답에 `previous_slugs`(옛 slug 목록, 최신순)를 additive로 더합니다.
8
+ `@roottale/cms-client`는 `previousSlugs`로 노출합니다. 주소가 바뀐 글을 옛 경로에서
9
+ 파생한 본문 예약 내부 링크 키로도 현재 주소에 연결할 수 있습니다.
10
+
11
+ ## 0.54.0
12
+
13
+ ### Minor Changes
14
+
15
+ - befa5bb: 콘텐츠 유형별 카테고리 주소와 카테고리 SEO 공개 필드에 더해, 1~3단계 부모·자식
16
+ 분류로 목록·허브·상세 주소를 구성하는 범용 콘텐츠 모델 계약을 추가합니다.
17
+ - ad805bd: 글 미리보기를 고객 사이트가 자기 글 템플릿으로 그릴 수 있게 합니다 — 관리자
18
+ 미리보기와 발행 결과가 다르던 문제의 해법.
19
+ - 공개 API `GET /v1/cms/public/posts/preview?token=`: 관리자 편집기가 발급한
20
+ 1시간짜리 토큰으로 초안(미발행 포함)을 발행 글과 같은 형식으로 돌려줍니다.
21
+ 없는 토큰 404, 만료 410 `preview_expired`, 응답 `cache-control: no-store`.
22
+ - `@roottale/cms-client/server`: `fetchPostPreview({ apiKey, token })`,
23
+ `isPreviewExpiredError`, `CmsPostPreviewContent`.
24
+ - `@roottale/cms-renderer-next`: `RootTaleBlogPost`에 `previewToken`·
25
+ `previewExpiredElement`(같은 템플릿으로 미리보기), `RootTalePreviewNotice`,
26
+ `buildPreviewMetadata`(항상 noindex/nofollow).
27
+ - 문서 `blog.md` "미리보기 페이지"·`api-reference.md`, 예시
28
+ `examples/nextjs/app/preview/post/[id]/page.tsx`.
29
+
30
+ ### Patch Changes
31
+
32
+ - 2a7c695: 카테고리 대표 이미지와 검색 문구를 공개 API에서 읽어 카테고리 모음 페이지의
33
+ 검색·공유 메타데이터에 사용할 수 있게 합니다.
34
+
35
+ ## 0.53.1
36
+
37
+ ### Patch Changes
38
+
39
+ - 6df15b6: 고객 사이트의 서버에서 발행 글과 페이지를 함께 검색할 수 있도록 `searchPosts`에 `type: "all"`과 언어 필터를 추가합니다. 검색 결과에는 콘텐츠 유형과 언어를 포함하고, `resolveSearchHitPath`가 블로그·고정 페이지·콘텐츠 유형·다국어 주소를 안전하게 계산합니다. Next.js 통합 검색 예시와 공개 API 문서도 함께 제공합니다.
40
+ - 1efecbb: 페이지·글·정보의 콘텐츠 모델 공개 계약과 `modelKey` 조회를 추가합니다. 개발자가 선언한 슬롯에서만 배너·팝업을 조회하고 접근성 있게 렌더하는 API, client, renderer, 예제 문서를 함께 제공합니다. 기존 collections와 collectionKey 계약은 유지합니다.
41
+
3
42
  ## 0.53.0
4
43
 
5
44
  ### Patch Changes
package/README.md CHANGED
@@ -67,6 +67,38 @@ try {
67
67
  }
68
68
  ```
69
69
 
70
+ ## Site search
71
+
72
+ 발행된 글과 페이지를 함께 검색할 때는 서버에서 `type: "all"`을 지정합니다.
73
+ 콘텐츠 유형마다 상세 주소가 다를 수 있으므로 결과 URL을 직접 조립하지 않습니다.
74
+
75
+ ```ts
76
+ import {
77
+ fetchCollections,
78
+ resolveSearchHitPath,
79
+ searchPosts,
80
+ } from "@roottale/cms-client/server";
81
+
82
+ const [hits, collections] = await Promise.all([
83
+ searchPosts({
84
+ apiKey: process.env.ROOTTALE_API_KEY!,
85
+ query: "상담",
86
+ type: "all",
87
+ locale: "ko",
88
+ limit: 20,
89
+ }),
90
+ fetchCollections({ apiKey: process.env.ROOTTALE_API_KEY! }),
91
+ ]);
92
+
93
+ const results = hits.flatMap((hit) => {
94
+ const href = resolveSearchHitPath(hit, collections);
95
+ return href ? [{ ...hit, href }] : [];
96
+ });
97
+ ```
98
+
99
+ `ROOTTALE_API_KEY`는 검색창이 있는 브라우저 코드에 넣지 말고 Server Component나
100
+ Route Handler에서만 사용하세요.
101
+
70
102
  ## Security boundary
71
103
 
72
104
  `assertServer()` throws if you import this in the browser. Shipping `rtlk_cust_*` to the client breaks the security model (ADR-0023 §5.1 #15). Keep all calls inside Server Components, Route Handlers, `getServerSideProps`, or build-time scripts.
package/dist/server.d.ts CHANGED
@@ -73,6 +73,8 @@ interface CmsPostContent {
73
73
  * 판정에 카테고리 파생보다 우선. 구 서버/미설정이면 null.
74
74
  */
75
75
  collectionKey: string | null;
76
+ /** 페이지·글·정보를 가리키는 안정적인 모델 key. 구 서버에서는 null. */
77
+ modelKey?: string | null;
76
78
  /** Lowercase kebab-case slug (1-120 chars). */
77
79
  slug: string;
78
80
  /**
@@ -85,6 +87,12 @@ interface CmsPostContent {
85
87
  * 자기 자신 1건만. 구 서버는 미포함 — optional (하위호환).
86
88
  */
87
89
  translations?: CmsPostTranslationRef[];
90
+ /**
91
+ * 이 글이 예전에 썼던 slug 목록(최신순). 주소 이동 뒤에도 옛 경로에서 파생한
92
+ * 본문 예약 내부 링크 키(`[[internal:…]]`)를 현재 글로 해석할 때 옛 경로도 같은
93
+ * 글로 등록하는 데 쓴다. 구 서버는 미포함 — optional.
94
+ */
95
+ previousSlugs?: string[];
88
96
  title: string;
89
97
  excerpt: string | null;
90
98
  /** Media id (resolved by renderer / consumer to URL). */
@@ -94,6 +102,9 @@ interface CmsPostContent {
94
102
  * → `media.variants_json` 를 해석해 제공. 대표 이미지 미설정 시 null.
95
103
  */
96
104
  featuredImageUrl: string | null;
105
+ /** 사이트 공통 공개 작성자 ID. 구 서버에서는 null. */
106
+ authorProfileId?: string | null;
107
+ /** @deprecated Use authorProfileId. */
97
108
  authorId: string | null;
98
109
  /** Public display name for the post author. Email is not exposed. */
99
110
  authorName: string | null;
@@ -108,6 +119,17 @@ interface CmsPostContent {
108
119
  authorSlug: string | null;
109
120
  /** Tiptap / Gutenberg-compatible Block JSON. Sanitization is renderer's responsibility. */
110
121
  bodyJson: Record<string, unknown>;
122
+ /**
123
+ * 원문 HTML 정본 — 외부에서 이관된 글처럼 HTML 이 정본인 경우에만 채워진다.
124
+ * 렌더러는 값이 있으면 sanitize 후 우선하고 없으면(null) body_json 으로
125
+ * 폴백한다. 구 서버는 미포함 — 매핑부에서 `?? null` 기본값.
126
+ * Sanitization 책임은 body_json 과 동일하게 렌더러에 있다.
127
+ *
128
+ * `?:` 인 이유 — 이 필드는 순수 가산분이라 기존 소비자가 모르고 지나가도
129
+ * 종전과 동일하게 동작해야 한다(값이 없으면 body_json 폴백). optional 로 두면
130
+ * 외부 사이트의 기존 객체 리터럴도 그대로 타입을 만족한다.
131
+ */
132
+ bodyHtml?: string | null;
111
133
  /** Public API only exposes `published`. */
112
134
  status: "published";
113
135
  /** Per-post meta (SEO overrides, canonical, og, ...). */
@@ -170,6 +192,8 @@ interface FetchPostsOptions {
170
192
  * 와 동시 지정 불가(서버가 400).
171
193
  */
172
194
  collectionKey?: string;
195
+ /** 특정 콘텐츠 모델의 항목만 조회한다. */
196
+ modelKey?: string;
173
197
  /**
174
198
  * 네거티브 스코프 — 어느 스트림에도 안 속한("미소속") 글만
175
199
  * (`blog-list-collection-scope.md` §2②). `collectionKey` 와 동시 지정 불가.
@@ -510,6 +534,9 @@ interface CmsRouteCollection {
510
534
  icon: string | null;
511
535
  /** 글별 상세 라우트 존재 여부 (기본 true — 하위 호환). false = 목록 전용 유형. */
512
536
  detail: boolean;
537
+ detailPath: "flat" | "category";
538
+ categoryPath: "namespaced" | "direct";
539
+ categoryCardinality: "multiple" | "exactly-one";
513
540
  }
514
541
  /**
515
542
  * 콘텐츠 유형(collections) fetch 캐시 tag 의 정본 이름 (ADR-0096 Phase C).
@@ -543,6 +570,40 @@ declare function fetchCollections(options: FetchCollectionsOptions): Promise<Cms
543
570
  * `fetchCollections().catch(() => fetchCollectionsSafeDefault())` 로 쓴다.
544
571
  */
545
572
  declare const fetchCollectionsSafeDefault: CmsRouteCollection[];
573
+ interface CmsContentModel {
574
+ key: string;
575
+ label: string;
576
+ cardinality: "singleton" | "collection";
577
+ preset: "page" | "article" | "entity" | null;
578
+ source: "code" | "site";
579
+ presentation: {
580
+ readonly kind: "data_only";
581
+ } | {
582
+ readonly kind: "fixed_page";
583
+ readonly path: string;
584
+ readonly templateKey?: string;
585
+ readonly allowedSections: readonly string[];
586
+ } | {
587
+ readonly kind: "detail";
588
+ readonly detailPath: string;
589
+ readonly templateKey?: string;
590
+ } | {
591
+ readonly kind: "category_tree";
592
+ readonly basePath: string;
593
+ readonly categoryDepth: number;
594
+ readonly templateKey?: string;
595
+ };
596
+ }
597
+ interface FetchContentModelsOptions {
598
+ apiKey: string;
599
+ baseUrl?: string;
600
+ siteId?: string;
601
+ signal?: AbortSignal;
602
+ revalidate?: number;
603
+ tags?: string[];
604
+ }
605
+ /** 활성 페이지·글·정보 모델의 안전한 공개 projection을 가져온다. */
606
+ declare function fetchContentModels(options: FetchContentModelsOptions): Promise<CmsContentModel[]>;
546
607
  /** 작가 1명 (camelCase) — author_slug 가 있고 발행 글이 1건 이상인 작가만. */
547
608
  interface RootTaleAuthor {
548
609
  /** 아카이브 URL slug (/blog/author/{slug}). */
@@ -620,8 +681,12 @@ declare function selectRelatedPosts(current: CmsPostContent, candidates: CmsPost
620
681
  */
621
682
  /** 분류 1건 + 요청 스코프 안의 발행 글 수. */
622
683
  interface CmsCategoryCount {
684
+ /** 안정 term id. 계층형 모델에서 post.terms의 id와 연결한다. */
685
+ id?: string | null;
623
686
  slug: string;
624
687
  name: string;
688
+ /** 부모 category term id. 루트면 null. */
689
+ parentId?: string | null;
625
690
  /** 요청 스코프(미소속/특정 스트림) 안에서 이 분류에 걸린 발행 글 수. 0 가능. */
626
691
  publishedPostCount: number;
627
692
  /** 이 분류가 귀속된 콘텐츠 유형 key (ADR-0060). 미귀속·구버전 응답이면 null. */
@@ -633,6 +698,13 @@ interface CmsCategoryCount {
633
698
  * 값을 볼 수 있다). 진단·어드민 표시용 참고값이다.
634
699
  */
635
700
  hubPromoted: boolean;
701
+ description: string | null;
702
+ seoTitle: string | null;
703
+ seoDescription: string | null;
704
+ imageMediaId?: string | null;
705
+ imageUrl?: string | null;
706
+ imageAlt?: string | null;
707
+ path: string | null;
636
708
  }
637
709
  interface CmsCategoryCounts {
638
710
  categories: CmsCategoryCount[];
@@ -801,7 +873,9 @@ interface SearchPostsOptions {
801
873
  /** 결과 수 1-50, default 10. */
802
874
  limit?: number;
803
875
  /** 기본 = `post` 만. page 포함 검색은 명시. */
804
- type?: CmsPostType;
876
+ type?: CmsPostType | "all";
877
+ /** BCP-47 locale. 미지정 시 사이트 기본 언어. */
878
+ locale?: string;
805
879
  siteId?: string;
806
880
  signal?: AbortSignal;
807
881
  /** ISR revalidate 초(opt-in, W0-9). 미지정 시 현행 동작 유지. */
@@ -811,6 +885,9 @@ interface SearchPostsOptions {
811
885
  interface CmsSearchHit {
812
886
  id: string;
813
887
  type: CmsPostType;
888
+ collectionKey: string | null;
889
+ modelKey: string | null;
890
+ locale: string;
814
891
  title: string;
815
892
  slug: string;
816
893
  excerpt: string | null;
@@ -819,10 +896,13 @@ interface CmsSearchHit {
819
896
  publishedAt: string;
820
897
  }
821
898
  /**
822
- * published 글 키워드 검색 (사이트 내 검색). 최신 발행순, body 미포함 슬림
899
+ * published 글 키워드 검색 (사이트 내 검색). 관련도순, body 미포함 슬림
823
900
  * hit — 상세는 slug 로 `fetchPost`. 구 서버(라우트 미배포)는 404 — 빈 배열.
824
901
  */
825
902
  declare function searchPosts(options: SearchPostsOptions): Promise<CmsSearchHit[]>;
903
+ type RoutableSearchHit = Pick<CmsSearchHit, "type" | "slug" | "collectionKey">;
904
+ /** 검색 hit을 사이트의 실제 공개 상세 주소로 바꾼다. 주소 없는 유형은 null. */
905
+ declare function resolveSearchHitPath(hit: RoutableSearchHit, collections: readonly Pick<CmsRouteCollection, "key" | "basePath" | "detail">[], locale?: string): string | null;
826
906
  /** 메뉴 항목 트리 노드 (깊이 ≤ 2). */
827
907
  interface RootTaleMenuItem {
828
908
  id: string;
@@ -912,6 +992,36 @@ interface FetchRedirectsOptions {
912
992
  */
913
993
  declare function fetchRedirects(options: FetchRedirectsOptions): Promise<RootTaleRedirect[]>;
914
994
 
995
+ declare const EXPOSURE_CACHE_TAG = "rt-exposures";
996
+ interface CmsExposureCampaign {
997
+ id: string;
998
+ slotKey: string;
999
+ kind: "banner" | "popup";
1000
+ content: {
1001
+ variant: string;
1002
+ eyebrow?: string;
1003
+ title: string;
1004
+ description?: string;
1005
+ assetUrl?: string;
1006
+ assetAlt?: string;
1007
+ linkLabel?: string;
1008
+ linkUrl?: string;
1009
+ };
1010
+ repeat: "always" | "session" | "day" | "never";
1011
+ }
1012
+ interface FetchExposureOptions {
1013
+ apiKey: string;
1014
+ baseUrl?: string;
1015
+ siteId?: string;
1016
+ slotKey: string;
1017
+ path: string;
1018
+ signal?: AbortSignal;
1019
+ revalidate?: number;
1020
+ tags?: string[];
1021
+ }
1022
+ /** 개발자가 선언한 슬롯과 현재 경로에 맞는 활성 캠페인 하나만 가져온다. */
1023
+ declare function fetchExposure(options: FetchExposureOptions): Promise<CmsExposureCampaign | null>;
1024
+
915
1025
  type SiteInquiryStatus = "pending" | "answered";
916
1026
  interface SiteInquiryListItem {
917
1027
  id: string;
@@ -983,6 +1093,43 @@ declare function fetchSiteInquiries(options: FetchSiteInquiriesOptions): Promise
983
1093
  declare function fetchSiteInquiry(options: FetchSiteInquiryOptions): Promise<SiteInquiryDetail | null>;
984
1094
  declare function submitSiteInquiry(options: SubmitSiteInquiryOptions): Promise<SubmitSiteInquiryResult>;
985
1095
 
1096
+ /**
1097
+ * 글 미리보기 — 어드민 편집기가 발급한 토큰으로 초안을 **발행 글과 같은 모양**으로
1098
+ * 받아 온다. 고객 사이트는 글 상세 템플릿을 그대로 재사용해 미리보기를 그리면
1099
+ * 된다(어드민이 대신 그리던 미리보기는 사이트 폰트·너비·목차와 달랐다).
1100
+ *
1101
+ * - 응답은 서버가 `cache-control: no-store` 로 보내고, 이 함수도 `cache: "no-store"`
1102
+ * 로 요청한다. 미리보기 페이지는 `export const dynamic = "force-dynamic"` 으로 두라.
1103
+ * - 토큰은 글 1건·1시간짜리. 만료되면 `CmsApiError`(status 410, code
1104
+ * `preview_expired`) 를 던진다 — `isPreviewExpiredError` 로 구분해 안내 문구를 보인다.
1105
+ */
1106
+ interface FetchPostPreviewOptions {
1107
+ /** `rtlk_cust_*` API key. Required. */
1108
+ readonly apiKey: string;
1109
+ /** Override the API base URL. Defaults to `https://api.roottale.com`. */
1110
+ readonly baseUrl?: string;
1111
+ /** 어드민 '미리보기'·'공유 링크' 가 URL `?token=` 으로 넘긴 토큰. */
1112
+ readonly token: string;
1113
+ readonly siteId?: string;
1114
+ readonly signal?: AbortSignal;
1115
+ }
1116
+ interface CmsPostPreviewInfo {
1117
+ /** 토큰 만료 시각(ISO). */
1118
+ readonly expiresAt: string;
1119
+ /** 글의 실제 상태. 본문 `status` 는 템플릿 재사용을 위해 항상 `published`. */
1120
+ readonly sourceStatus: "draft" | "pending" | "scheduled" | "published" | "private" | "trash";
1121
+ }
1122
+ interface CmsPostPreviewContent extends CmsPostContent {
1123
+ readonly preview: CmsPostPreviewInfo;
1124
+ }
1125
+ /** 만료된 미리보기 링크(410 `preview_expired`)인지 구분한다. */
1126
+ declare function isPreviewExpiredError(error: unknown): boolean;
1127
+ /**
1128
+ * 토큰이 없거나 다른 사이트의 것이면 `null`(404). 만료는 throw(410) — 두 경우를
1129
+ * 다르게 안내할 수 있게 구분한다.
1130
+ */
1131
+ declare function fetchPostPreview(options: FetchPostPreviewOptions): Promise<CmsPostPreviewContent | null>;
1132
+
986
1133
  /**
987
1134
  * 설정류 fetch 캐시 tag 한 벌 (ADR-0096 Phase C).
988
1135
  *
@@ -995,7 +1142,7 @@ declare function submitSiteInquiry(options: SubmitSiteInquiryOptions): Promise<S
995
1142
  */
996
1143
  /**
997
1144
  * 어드민 "설정" 저장으로 낡는 fetch 캐시 tag 전부 — 테마·사업장 정보·메뉴·
998
- * 블로그 표시 설정·콘텐츠 유형.
1145
+ * 블로그 표시 설정·콘텐츠 유형·노출 캠페인.
999
1146
  *
1000
1147
  * 수신측(`createRevalidateRoute`)이 `theme.updated` 한 번에 이 목록을 통째로
1001
1148
  * 무효화한다. 사이트가 이 중 일부 fetch 만 쓰더라도 안 쓰는 tag 의
@@ -1285,4 +1432,4 @@ declare function formatKoreanPhoneNumber(input: string): string;
1285
1432
  */
1286
1433
  declare function submitInquiry(options: SubmitInquiryOptions): Promise<SubmitInquiryResult>;
1287
1434
 
1288
- export { type ActionDockAction, type ActionDockKind, type ActionDockPosition, type ActionDockSettings, type AnalyticsTagConfig, type AnalyticsTagProvider, type AnnouncementItem, type AnnouncementSettings, type AnnouncementTone, type AnnouncementVariant, type ArticleSchemaInput, BLOG_SETTINGS_CACHE_TAG, BUSINESS_CACHE_TAG, type BusinessDayCode, type BusinessOpeningHours, type BusinessType, CMS_CLIENT_VERSION, COLLECTIONS_CACHE_TAG, CmsApiError, type CmsArchiveRelatedGroup, type CmsArchiveRelatedPost, type CmsCategoryCount, type CmsCategoryCounts, type CmsFieldMetaEntry, type CmsPostContent, type CmsPostContentPage, type CmsPostTranslationRef, type CmsPostType, type CmsRouteCollection, type CmsSearchHit, type CmsTaxonomyKind, type CmsTermRef, DEFAULT_BLOG_SETTINGS, type FetchAnalyticsOptions, type FetchAuthorsOptions, type FetchBlogSettingsOptions, type FetchBusinessProfileOptions, type FetchCategoryCountsOptions, type FetchCollectionsOptions, type FetchMenuOptions, type FetchMenusOptions, type FetchPageBySlugOptions, type FetchPostOptions, type FetchPostsOptions, type FetchRedirectsOptions, type FetchSiteInquiriesOptions, type FetchSiteInquiryOptions, type FetchThemeOptions, INQUIRY_ERROR_MESSAGES, InquiryAttribution, type InquiryBoardSettings, type InquiryVertical, LOCAL_BUSINESS_MAX_SERVICES, LOCAL_BUSINESS_SERVICE_MAX_LENGTH, type LocalBusinessProfileInput, MENUS_CACHE_TAG, type ResolvedPostDisplay, type RootTaleAuthor, type RootTaleBlogPostCta, type RootTaleBlogSettings, type RootTaleBusinessProfile, type RootTaleMenu, type RootTaleMenuItem, type RootTaleRedirect, type RootTaleSiteProfile, type RootTaleSitemapSettings, type RootTaleTheme, type RssFeedInput, type RssItemInput, SETTINGS_CACHE_TAGS, type SearchPostsOptions, type SiteAnalyticsTags, type SiteInquiryDetail, type SiteInquiryListItem, type SiteInquiryListPage, type SiteInquiryStatus, type SiteNavColumn, type SiteNavCta, type SiteNavGroup, type SiteNavLink, type SiteNavSettings, type SubmitInquiryFields, type SubmitInquiryOptions, type SubmitInquiryResult, type SubmitSiteInquiryFields, type SubmitSiteInquiryOptions, type SubmitSiteInquiryResult, THEME_CACHE_TAG, articleSchema, breadcrumbSchema, businessProfileFromWire, collectionPageSchema, contentIdMeta, faqSchema, fetchAnalyticsConfig, fetchAuthors, fetchBlogSettings, fetchBusinessProfile, fetchCategoryCounts, fetchCollections, fetchCollectionsSafeDefault, fetchMenu, fetchMenus, fetchPageBySlug, fetchPost, fetchPosts, fetchRedirects, fetchSiteInquiries, fetchSiteInquiry, fetchTheme, formatKoreanPhoneNumber, generateRssXml, inquiryErrorMessage, jsonLdJson, jsonLdScript, localBusinessSchema, organizationSchema, parseInquiryRedirect, profilePageSchema, resolvePostDisplay, rssItemsFromPosts, searchPosts, selectRelatedPosts, submitInquiry, submitSiteInquiry, websiteSchema };
1435
+ export { type ActionDockAction, type ActionDockKind, type ActionDockPosition, type ActionDockSettings, type AnalyticsTagConfig, type AnalyticsTagProvider, type AnnouncementItem, type AnnouncementSettings, type AnnouncementTone, type AnnouncementVariant, type ArticleSchemaInput, BLOG_SETTINGS_CACHE_TAG, BUSINESS_CACHE_TAG, type BusinessDayCode, type BusinessOpeningHours, type BusinessType, CMS_CLIENT_VERSION, COLLECTIONS_CACHE_TAG, CmsApiError, type CmsArchiveRelatedGroup, type CmsArchiveRelatedPost, type CmsCategoryCount, type CmsCategoryCounts, type CmsContentModel, type CmsExposureCampaign, type CmsFieldMetaEntry, type CmsPostContent, type CmsPostContentPage, type CmsPostPreviewContent, type CmsPostPreviewInfo, type CmsPostTranslationRef, type CmsPostType, type CmsRouteCollection, type CmsSearchHit, type CmsTaxonomyKind, type CmsTermRef, DEFAULT_BLOG_SETTINGS, EXPOSURE_CACHE_TAG, type FetchAnalyticsOptions, type FetchAuthorsOptions, type FetchBlogSettingsOptions, type FetchBusinessProfileOptions, type FetchCategoryCountsOptions, type FetchCollectionsOptions, type FetchContentModelsOptions, type FetchExposureOptions, type FetchMenuOptions, type FetchMenusOptions, type FetchPageBySlugOptions, type FetchPostOptions, type FetchPostPreviewOptions, type FetchPostsOptions, type FetchRedirectsOptions, type FetchSiteInquiriesOptions, type FetchSiteInquiryOptions, type FetchThemeOptions, INQUIRY_ERROR_MESSAGES, InquiryAttribution, type InquiryBoardSettings, type InquiryVertical, LOCAL_BUSINESS_MAX_SERVICES, LOCAL_BUSINESS_SERVICE_MAX_LENGTH, type LocalBusinessProfileInput, MENUS_CACHE_TAG, type ResolvedPostDisplay, type RootTaleAuthor, type RootTaleBlogPostCta, type RootTaleBlogSettings, type RootTaleBusinessProfile, type RootTaleMenu, type RootTaleMenuItem, type RootTaleRedirect, type RootTaleSiteProfile, type RootTaleSitemapSettings, type RootTaleTheme, type RssFeedInput, type RssItemInput, SETTINGS_CACHE_TAGS, type SearchPostsOptions, type SiteAnalyticsTags, type SiteInquiryDetail, type SiteInquiryListItem, type SiteInquiryListPage, type SiteInquiryStatus, type SiteNavColumn, type SiteNavCta, type SiteNavGroup, type SiteNavLink, type SiteNavSettings, type SubmitInquiryFields, type SubmitInquiryOptions, type SubmitInquiryResult, type SubmitSiteInquiryFields, type SubmitSiteInquiryOptions, type SubmitSiteInquiryResult, THEME_CACHE_TAG, articleSchema, breadcrumbSchema, businessProfileFromWire, collectionPageSchema, contentIdMeta, faqSchema, fetchAnalyticsConfig, fetchAuthors, fetchBlogSettings, fetchBusinessProfile, fetchCategoryCounts, fetchCollections, fetchCollectionsSafeDefault, fetchContentModels, fetchExposure, fetchMenu, fetchMenus, fetchPageBySlug, fetchPost, fetchPostPreview, fetchPosts, fetchRedirects, fetchSiteInquiries, fetchSiteInquiry, fetchTheme, formatKoreanPhoneNumber, generateRssXml, inquiryErrorMessage, isPreviewExpiredError, jsonLdJson, jsonLdScript, localBusinessSchema, organizationSchema, parseInquiryRedirect, profilePageSchema, resolvePostDisplay, resolveSearchHitPath, rssItemsFromPosts, searchPosts, selectRelatedPosts, submitInquiry, submitSiteInquiry, websiteSchema };