@roottale/cms-core 0.65.1 → 0.67.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/dist/index.d.cts CHANGED
@@ -207,9 +207,17 @@ declare function validateCollections(collections: readonly RouteCollection[]): s
207
207
  * FAQ·도움말·문서처럼 하나의 모델이 여러 단계 분류 허브를 가지는 경우에 쓴다.
208
208
  * 저장소나 프레임워크를 모르며, 공개 API와 ROOT-ADMIN이 같은 계산을 재사용한다.
209
209
  */
210
+ /**
211
+ * 글을 붙일 수 있는 분류.
212
+ * - `deepest`(기본): `categoryDepth` 단계의 말단 분류에만 붙는다.
213
+ * - `leaf`: 하위 분류가 없는 분류면 단계와 무관하게 붙는다(`categoryDepth`는 최대 단계).
214
+ * 하위가 필요한 영역만 나누고 나머지는 상위 분류에 바로 글을 쓸 때 쓴다.
215
+ */
216
+ type CategoryTreeEntryCategory = "deepest" | "leaf";
210
217
  interface CategoryTreePresentation {
211
218
  readonly basePath: string;
212
219
  readonly categoryDepth: number;
220
+ readonly entryCategory?: CategoryTreeEntryCategory;
213
221
  }
214
222
  interface CategoryTreeTerm {
215
223
  readonly id: string;
@@ -224,10 +232,19 @@ interface CategoryTreeEntry {
224
232
  }>;
225
233
  }
226
234
  /**
227
- * 선택한 말단 분류부터 루트까지의 사슬을 루트→말단 순서로 돌려준다.
228
- * 끊긴 부모·순환·중복 id·깊이 불일치·말단이 아닌 선택은 null로 닫는다.
235
+ * 글 주소에 쓰는 분류의 루트→분류 사슬. 주소를 만들 수 없으면 null.
236
+ *
237
+ * - `deepest`: 정확히 `categoryDepth` 단계의 말단이어야 한다.
238
+ * - `leaf`: `categoryDepth` 이하면 된다. 하위가 없는지는 *새로 고를 때*만 본다
239
+ * (`resolveCategoryTreeSelection`) — 글이 붙은 뒤 하위 분류가 생겨도 이미 발행한
240
+ * 글의 주소는 그대로 살아 있어야 한다.
241
+ */
242
+ declare function resolveCategoryTreeChain(presentation: CategoryTreePresentation, termId: string, terms: readonly CategoryTreeTerm[]): CategoryTreeTerm[] | null;
243
+ /**
244
+ * 글에 새로 고를 수 있는 분류의 사슬 — 주소를 만들 수 있고 지금 하위 분류가 없어야
245
+ * 한다. 편집기 선택지와 발행 검사가 같은 규칙을 쓴다.
229
246
  */
230
- declare function resolveCategoryTreeChain(presentation: CategoryTreePresentation, leafId: string, terms: readonly CategoryTreeTerm[]): CategoryTreeTerm[] | null;
247
+ declare function resolveCategoryTreeSelection(presentation: CategoryTreePresentation, termId: string, terms: readonly CategoryTreeTerm[]): CategoryTreeTerm[] | null;
231
248
  /** 루트부터 선택 분류까지 모든 허브 주소. */
232
249
  declare function resolveCategoryTreeHubPaths(presentation: CategoryTreePresentation, termId: string, terms: readonly CategoryTreeTerm[]): string[] | null;
233
250
  /** 계층형 분류 모델 항목의 정규 상세 주소. */
@@ -258,6 +275,7 @@ type PublicPathPresentation = {
258
275
  readonly kind: "category_tree";
259
276
  readonly basePath: string;
260
277
  readonly categoryDepth: number;
278
+ readonly entryCategory?: CategoryTreeEntryCategory;
261
279
  };
262
280
  interface PublicPathPost {
263
281
  readonly slug: string;
@@ -612,4 +630,550 @@ declare function isSectionContentPropPath(sectionType: string, path: readonly (s
612
630
  declare function findSectionLockViolations(beforeDoc: unknown, afterDoc: unknown): SectionLockViolation[];
613
631
  declare function formatSectionLockViolations(violations: readonly SectionLockViolation[]): string;
614
632
 
615
- export { BLOCK_NAME_PATTERN, type BindingResolver, type Block, type BlockBinding, type BlockDefinition, type BlockRegistry, CMS_FONT_SIZES, CMS_IMAGE_WIDTHS, CMS_LINE_HEIGHTS, CMS_PARAGRAPH_SPACINGS, type CategoryTreeEntry, type CategoryTreePresentation, type CategoryTreeTerm, type ClientHydrationSpec, DEFAULT_SITE_PATTERN_PRESENTATION, EMPTY_SITE_PATTERN_PLACEMENTS, type EmbedProvider, FIELD_BINDING_SOURCE, FIELD_BINDING_SOURCE_ALIAS, type FaqEntry, IMAGE_ALT_MAX_LENGTH, INTERNAL_CONTENT_LINK_CLASS, INTERNAL_CONTENT_LINK_PENDING_ATTR, INTERNAL_CONTENT_LINK_PENDING_CLASS, INTERNAL_CONTENT_LINK_TOKEN_SOURCE, type InternalContentLinkResolver, type InternalContentLinkToken, LEGACY_BLOG_DETAIL_PATH, type NormalizedEmbed, PHASE_1_CORE_BLOCKS, PHASE_1_CSP, POST_FOOTER_SLOT, type PatternSlots, type Phase1CoreBlockName, type PreviewTokenPayload, type PublicPathContext, type PublicPathPost, type PublicPathPresentation, type RoutablePost, type RouteCollection, SITE_PATTERN_BUTTON_COLORS_MAX, SITE_PATTERN_KEY_PATTERN, SITE_PATTERN_PLACEMENTS_KEY, SITE_PATTERN_SLOTS, type SectionLock, type SectionLockViolation, type SectionLockViolationCode, type SitePatternLayout, type SitePatternLinkStyle, type SitePatternPlacementRule, type SitePatternPlacements, type SitePatternPresentation, type SitePatternSlotKey, applyBlockBindings, bindingSrcValue, bindingTextValue, blockSchema, boundFieldValue, chainResolvers, cmsFontSize, cmsImageAlign, cmsImageStyle, cmsImageWidth, cmsLineHeight, cmsParagraphSpacing, createFieldBindingResolver, emptyPatternSlots, ensureImportedHtmlDocumentRoots, ensureStableIds, extractFaqEntries, faqPageJsonLd, findInternalContentLinkTokens, findSectionLockViolations, findSitePatternPlacementRule, formatSectionLockViolations, htmlToPlainText, injectStableIdsTree, internalContentKeyFromPath, internalContentLinkResolverFrom, internalContentPathIndex, isAllowedEmbedSrc, isAllowedMapEmbedSrc, isInCollectionMode, isSectionContentPropPath, isSitePatternSlotKey, isValidBlock, isValidSitePatternKey, issuePreviewToken, normalizeEmbed, normalizeHexColor, normalizeImageAlt, parseBlock, postsForCollection, postsInAnyCollection, postsNotInAnyCollection, readSitePatternPlacements, readSitePatternPresentation, referencedSitePatternKeys, renderInternalContentLinksInHtml, renderInternalContentLinksInText, resolveCategoryPath, resolveCategoryTreeChain, resolveCategoryTreeEntryPath, resolveCategoryTreeHubPaths, resolvePatternSlots, resolvePostCategorySlug, resolvePostCollection, resolvePostPath, resolvePostPublicPath, resolvePostUrl, sanitizeHtml, sanitizeImportedCss, sanitizeImportedHtml, scopeImportedCss, serializeBlock, setSitePatternPlacementRule, sitePatternButtonColor, sitePatternPresentationAttributes, validateCollections, verifyPreviewToken };
633
+ declare const METADATA_FIELDS: readonly ["title", "description", "ogImage", "ogImageAlt", "noindex", "nofollow"];
634
+ declare const MetadataFieldSchema: z.ZodEnum<["title", "description", "ogImage", "ogImageAlt", "noindex", "nofollow"]>;
635
+ type MetadataField = z.infer<typeof MetadataFieldSchema>;
636
+ declare const MetadataTargetKindSchema: z.ZodEnum<["route", "post", "term"]>;
637
+ type MetadataTargetKind = z.infer<typeof MetadataTargetKindSchema>;
638
+ /** Empty/omitted values inherit defaults. Canonical remains owned by site routing. */
639
+ declare const MetadataValuesSchema: z.ZodObject<{
640
+ title: z.ZodOptional<z.ZodString>;
641
+ description: z.ZodOptional<z.ZodString>;
642
+ ogImage: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
643
+ ogImageAlt: z.ZodOptional<z.ZodString>;
644
+ noindex: z.ZodOptional<z.ZodBoolean>;
645
+ nofollow: z.ZodOptional<z.ZodBoolean>;
646
+ }, "strict", z.ZodTypeAny, {
647
+ title?: string | undefined;
648
+ description?: string | undefined;
649
+ ogImage?: string | undefined;
650
+ ogImageAlt?: string | undefined;
651
+ noindex?: boolean | undefined;
652
+ nofollow?: boolean | undefined;
653
+ }, {
654
+ title?: string | undefined;
655
+ description?: string | undefined;
656
+ ogImage?: string | undefined;
657
+ ogImageAlt?: string | undefined;
658
+ noindex?: boolean | undefined;
659
+ nofollow?: boolean | undefined;
660
+ }>;
661
+ type MetadataValues = z.infer<typeof MetadataValuesSchema>;
662
+ declare const MetadataPatchSchema: z.ZodObject<{
663
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
664
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
665
+ ogImage: z.ZodOptional<z.ZodNullable<z.ZodEffects<z.ZodString, string, string>>>;
666
+ ogImageAlt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
667
+ noindex: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
668
+ nofollow: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
669
+ }, "strict", z.ZodTypeAny, {
670
+ title?: string | null | undefined;
671
+ description?: string | null | undefined;
672
+ ogImage?: string | null | undefined;
673
+ ogImageAlt?: string | null | undefined;
674
+ noindex?: boolean | null | undefined;
675
+ nofollow?: boolean | null | undefined;
676
+ }, {
677
+ title?: string | null | undefined;
678
+ description?: string | null | undefined;
679
+ ogImage?: string | null | undefined;
680
+ ogImageAlt?: string | null | undefined;
681
+ noindex?: boolean | null | undefined;
682
+ nofollow?: boolean | null | undefined;
683
+ }>;
684
+ type MetadataPatch = z.infer<typeof MetadataPatchSchema>;
685
+ declare const MetadataRobotsPolicySchema: z.ZodObject<{
686
+ forceNoindex: z.ZodOptional<z.ZodBoolean>;
687
+ forceNofollow: z.ZodOptional<z.ZodBoolean>;
688
+ }, "strict", z.ZodTypeAny, {
689
+ forceNoindex?: boolean | undefined;
690
+ forceNofollow?: boolean | undefined;
691
+ }, {
692
+ forceNoindex?: boolean | undefined;
693
+ forceNofollow?: boolean | undefined;
694
+ }>;
695
+ type MetadataRobotsPolicy = z.infer<typeof MetadataRobotsPolicySchema>;
696
+ interface MetadataTarget {
697
+ readonly kind: MetadataTargetKind;
698
+ readonly key: string;
699
+ readonly locale: string;
700
+ readonly label: string;
701
+ readonly path: string | null;
702
+ /** Opaque CAS token. Consumers must not parse or increment it. */
703
+ readonly version: string;
704
+ readonly overrides: MetadataValues;
705
+ readonly defaults: MetadataValues;
706
+ readonly fallback?: MetadataValues;
707
+ readonly effective: MetadataValues;
708
+ readonly supportedFields: MetadataField[];
709
+ readonly robots?: MetadataRobotsPolicy;
710
+ readonly connection: "connected" | "unconnected" | "removed";
711
+ }
712
+ interface PublicRouteMetadata {
713
+ readonly routeKey: string;
714
+ readonly locale: string;
715
+ readonly path: string;
716
+ readonly version: string;
717
+ readonly overrides: MetadataValues;
718
+ readonly defaults: MetadataValues;
719
+ readonly fallback?: MetadataValues;
720
+ readonly effective: MetadataValues;
721
+ readonly supportedFields: MetadataField[];
722
+ readonly robots?: MetadataRobotsPolicy;
723
+ }
724
+ /** Read recognized, valid legacy fields without losing false or accepting arbitrary head HTML. */
725
+ declare function readMetadataValues(input: unknown): MetadataValues;
726
+ /** Preserve legacy namespaces (including canonical) while changing only the requested fields. */
727
+ declare function mergeMetadataPatch(current: Record<string, unknown>, input: MetadataPatch): Record<string, unknown>;
728
+
729
+ /** 같은 필드의 우선순위: 직접 설정 → 콘텐츠/코드 기본값 → 사이트 기본값 → 코드 fallback. */
730
+ interface MetadataResolutionInput {
731
+ overrides?: MetadataValues | null;
732
+ defaults?: MetadataValues | null;
733
+ siteDefaults?: MetadataValues | null;
734
+ fallback?: MetadataValues | null;
735
+ robots?: MetadataRobotsPolicy;
736
+ /** 상대 이미지 경로를 절대 주소로 바꿀 기준 URL. canonical 정책에는 관여하지 않는다. */
737
+ imageBaseUrl?: string;
738
+ }
739
+ /** 글·분류·코드 경로가 공유하는 순수 해석기. false는 상속을 덮는 명시값이다. */
740
+ declare function resolveMetadata(input: MetadataResolutionInput): MetadataValues;
741
+
742
+ /** A fixed set of content cleanup rules; never accept executable expressions or caller regexes. */
743
+ declare const MetadataTextRuleSchema: z.ZodEffects<z.ZodObject<{
744
+ source: z.ZodOptional<z.ZodEnum<["content", "fallback"]>>;
745
+ stripLeadingLabel: z.ZodOptional<z.ZodEnum<["question", "answer"]>>;
746
+ replaceLineBreakTokens: z.ZodOptional<z.ZodBoolean>;
747
+ removeEmDashes: z.ZodOptional<z.ZodBoolean>;
748
+ normalizeWhitespace: z.ZodOptional<z.ZodBoolean>;
749
+ maxLength: z.ZodOptional<z.ZodNumber>;
750
+ ellipsis: z.ZodOptional<z.ZodString>;
751
+ fallback: z.ZodOptional<z.ZodString>;
752
+ fallbackWithParent: z.ZodOptional<z.ZodString>;
753
+ fallbackWithoutParent: z.ZodOptional<z.ZodString>;
754
+ fallbackBySlug: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
755
+ }, "strict", z.ZodTypeAny, {
756
+ source?: "content" | "fallback" | undefined;
757
+ fallback?: string | undefined;
758
+ stripLeadingLabel?: "question" | "answer" | undefined;
759
+ replaceLineBreakTokens?: boolean | undefined;
760
+ removeEmDashes?: boolean | undefined;
761
+ normalizeWhitespace?: boolean | undefined;
762
+ maxLength?: number | undefined;
763
+ ellipsis?: string | undefined;
764
+ fallbackWithParent?: string | undefined;
765
+ fallbackWithoutParent?: string | undefined;
766
+ fallbackBySlug?: Record<string, string> | undefined;
767
+ }, {
768
+ source?: "content" | "fallback" | undefined;
769
+ fallback?: string | undefined;
770
+ stripLeadingLabel?: "question" | "answer" | undefined;
771
+ replaceLineBreakTokens?: boolean | undefined;
772
+ removeEmDashes?: boolean | undefined;
773
+ normalizeWhitespace?: boolean | undefined;
774
+ maxLength?: number | undefined;
775
+ ellipsis?: string | undefined;
776
+ fallbackWithParent?: string | undefined;
777
+ fallbackWithoutParent?: string | undefined;
778
+ fallbackBySlug?: Record<string, string> | undefined;
779
+ }>, {
780
+ source?: "content" | "fallback" | undefined;
781
+ fallback?: string | undefined;
782
+ stripLeadingLabel?: "question" | "answer" | undefined;
783
+ replaceLineBreakTokens?: boolean | undefined;
784
+ removeEmDashes?: boolean | undefined;
785
+ normalizeWhitespace?: boolean | undefined;
786
+ maxLength?: number | undefined;
787
+ ellipsis?: string | undefined;
788
+ fallbackWithParent?: string | undefined;
789
+ fallbackWithoutParent?: string | undefined;
790
+ fallbackBySlug?: Record<string, string> | undefined;
791
+ }, {
792
+ source?: "content" | "fallback" | undefined;
793
+ fallback?: string | undefined;
794
+ stripLeadingLabel?: "question" | "answer" | undefined;
795
+ replaceLineBreakTokens?: boolean | undefined;
796
+ removeEmDashes?: boolean | undefined;
797
+ normalizeWhitespace?: boolean | undefined;
798
+ maxLength?: number | undefined;
799
+ ellipsis?: string | undefined;
800
+ fallbackWithParent?: string | undefined;
801
+ fallbackWithoutParent?: string | undefined;
802
+ fallbackBySlug?: Record<string, string> | undefined;
803
+ }>;
804
+ type MetadataTextRule = z.infer<typeof MetadataTextRuleSchema>;
805
+ declare const MetadataDefaultRulesSchema: z.ZodEffects<z.ZodObject<{
806
+ title: z.ZodOptional<z.ZodEffects<z.ZodObject<{
807
+ source: z.ZodOptional<z.ZodEnum<["content", "fallback"]>>;
808
+ stripLeadingLabel: z.ZodOptional<z.ZodEnum<["question", "answer"]>>;
809
+ replaceLineBreakTokens: z.ZodOptional<z.ZodBoolean>;
810
+ removeEmDashes: z.ZodOptional<z.ZodBoolean>;
811
+ normalizeWhitespace: z.ZodOptional<z.ZodBoolean>;
812
+ maxLength: z.ZodOptional<z.ZodNumber>;
813
+ ellipsis: z.ZodOptional<z.ZodString>;
814
+ fallback: z.ZodOptional<z.ZodString>;
815
+ fallbackWithParent: z.ZodOptional<z.ZodString>;
816
+ fallbackWithoutParent: z.ZodOptional<z.ZodString>;
817
+ fallbackBySlug: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
818
+ }, "strict", z.ZodTypeAny, {
819
+ source?: "content" | "fallback" | undefined;
820
+ fallback?: string | undefined;
821
+ stripLeadingLabel?: "question" | "answer" | undefined;
822
+ replaceLineBreakTokens?: boolean | undefined;
823
+ removeEmDashes?: boolean | undefined;
824
+ normalizeWhitespace?: boolean | undefined;
825
+ maxLength?: number | undefined;
826
+ ellipsis?: string | undefined;
827
+ fallbackWithParent?: string | undefined;
828
+ fallbackWithoutParent?: string | undefined;
829
+ fallbackBySlug?: Record<string, string> | undefined;
830
+ }, {
831
+ source?: "content" | "fallback" | undefined;
832
+ fallback?: string | undefined;
833
+ stripLeadingLabel?: "question" | "answer" | undefined;
834
+ replaceLineBreakTokens?: boolean | undefined;
835
+ removeEmDashes?: boolean | undefined;
836
+ normalizeWhitespace?: boolean | undefined;
837
+ maxLength?: number | undefined;
838
+ ellipsis?: string | undefined;
839
+ fallbackWithParent?: string | undefined;
840
+ fallbackWithoutParent?: string | undefined;
841
+ fallbackBySlug?: Record<string, string> | undefined;
842
+ }>, {
843
+ source?: "content" | "fallback" | undefined;
844
+ fallback?: string | undefined;
845
+ stripLeadingLabel?: "question" | "answer" | undefined;
846
+ replaceLineBreakTokens?: boolean | undefined;
847
+ removeEmDashes?: boolean | undefined;
848
+ normalizeWhitespace?: boolean | undefined;
849
+ maxLength?: number | undefined;
850
+ ellipsis?: string | undefined;
851
+ fallbackWithParent?: string | undefined;
852
+ fallbackWithoutParent?: string | undefined;
853
+ fallbackBySlug?: Record<string, string> | undefined;
854
+ }, {
855
+ source?: "content" | "fallback" | undefined;
856
+ fallback?: string | undefined;
857
+ stripLeadingLabel?: "question" | "answer" | undefined;
858
+ replaceLineBreakTokens?: boolean | undefined;
859
+ removeEmDashes?: boolean | undefined;
860
+ normalizeWhitespace?: boolean | undefined;
861
+ maxLength?: number | undefined;
862
+ ellipsis?: string | undefined;
863
+ fallbackWithParent?: string | undefined;
864
+ fallbackWithoutParent?: string | undefined;
865
+ fallbackBySlug?: Record<string, string> | undefined;
866
+ }>>;
867
+ description: z.ZodOptional<z.ZodEffects<z.ZodObject<{
868
+ source: z.ZodOptional<z.ZodEnum<["content", "fallback"]>>;
869
+ stripLeadingLabel: z.ZodOptional<z.ZodEnum<["question", "answer"]>>;
870
+ replaceLineBreakTokens: z.ZodOptional<z.ZodBoolean>;
871
+ removeEmDashes: z.ZodOptional<z.ZodBoolean>;
872
+ normalizeWhitespace: z.ZodOptional<z.ZodBoolean>;
873
+ maxLength: z.ZodOptional<z.ZodNumber>;
874
+ ellipsis: z.ZodOptional<z.ZodString>;
875
+ fallback: z.ZodOptional<z.ZodString>;
876
+ fallbackWithParent: z.ZodOptional<z.ZodString>;
877
+ fallbackWithoutParent: z.ZodOptional<z.ZodString>;
878
+ fallbackBySlug: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
879
+ }, "strict", z.ZodTypeAny, {
880
+ source?: "content" | "fallback" | undefined;
881
+ fallback?: string | undefined;
882
+ stripLeadingLabel?: "question" | "answer" | undefined;
883
+ replaceLineBreakTokens?: boolean | undefined;
884
+ removeEmDashes?: boolean | undefined;
885
+ normalizeWhitespace?: boolean | undefined;
886
+ maxLength?: number | undefined;
887
+ ellipsis?: string | undefined;
888
+ fallbackWithParent?: string | undefined;
889
+ fallbackWithoutParent?: string | undefined;
890
+ fallbackBySlug?: Record<string, string> | undefined;
891
+ }, {
892
+ source?: "content" | "fallback" | undefined;
893
+ fallback?: string | undefined;
894
+ stripLeadingLabel?: "question" | "answer" | undefined;
895
+ replaceLineBreakTokens?: boolean | undefined;
896
+ removeEmDashes?: boolean | undefined;
897
+ normalizeWhitespace?: boolean | undefined;
898
+ maxLength?: number | undefined;
899
+ ellipsis?: string | undefined;
900
+ fallbackWithParent?: string | undefined;
901
+ fallbackWithoutParent?: string | undefined;
902
+ fallbackBySlug?: Record<string, string> | undefined;
903
+ }>, {
904
+ source?: "content" | "fallback" | undefined;
905
+ fallback?: string | undefined;
906
+ stripLeadingLabel?: "question" | "answer" | undefined;
907
+ replaceLineBreakTokens?: boolean | undefined;
908
+ removeEmDashes?: boolean | undefined;
909
+ normalizeWhitespace?: boolean | undefined;
910
+ maxLength?: number | undefined;
911
+ ellipsis?: string | undefined;
912
+ fallbackWithParent?: string | undefined;
913
+ fallbackWithoutParent?: string | undefined;
914
+ fallbackBySlug?: Record<string, string> | undefined;
915
+ }, {
916
+ source?: "content" | "fallback" | undefined;
917
+ fallback?: string | undefined;
918
+ stripLeadingLabel?: "question" | "answer" | undefined;
919
+ replaceLineBreakTokens?: boolean | undefined;
920
+ removeEmDashes?: boolean | undefined;
921
+ normalizeWhitespace?: boolean | undefined;
922
+ maxLength?: number | undefined;
923
+ ellipsis?: string | undefined;
924
+ fallbackWithParent?: string | undefined;
925
+ fallbackWithoutParent?: string | undefined;
926
+ fallbackBySlug?: Record<string, string> | undefined;
927
+ }>>;
928
+ useFirstBodyImage: z.ZodOptional<z.ZodBoolean>;
929
+ useTermImage: z.ZodOptional<z.ZodBoolean>;
930
+ imageAltSource: z.ZodOptional<z.ZodEnum<["content", "title"]>>;
931
+ legacyImageSource: z.ZodOptional<z.ZodLiteral<"legacy-thumbnail">>;
932
+ imageAllowedOrigins: z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodString, string, string>, "many">>;
933
+ legacyImageAllowedOrigins: z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodString, string, string>, "many">>;
934
+ normalizeCloudflareImages: z.ZodOptional<z.ZodBoolean>;
935
+ fallback: z.ZodOptional<z.ZodObject<{
936
+ title: z.ZodOptional<z.ZodString>;
937
+ description: z.ZodOptional<z.ZodString>;
938
+ ogImage: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
939
+ ogImageAlt: z.ZodOptional<z.ZodString>;
940
+ noindex: z.ZodOptional<z.ZodBoolean>;
941
+ nofollow: z.ZodOptional<z.ZodBoolean>;
942
+ }, "strict", z.ZodTypeAny, {
943
+ title?: string | undefined;
944
+ description?: string | undefined;
945
+ ogImage?: string | undefined;
946
+ ogImageAlt?: string | undefined;
947
+ noindex?: boolean | undefined;
948
+ nofollow?: boolean | undefined;
949
+ }, {
950
+ title?: string | undefined;
951
+ description?: string | undefined;
952
+ ogImage?: string | undefined;
953
+ ogImageAlt?: string | undefined;
954
+ noindex?: boolean | undefined;
955
+ nofollow?: boolean | undefined;
956
+ }>>;
957
+ }, "strict", z.ZodTypeAny, {
958
+ title?: {
959
+ source?: "content" | "fallback" | undefined;
960
+ fallback?: string | undefined;
961
+ stripLeadingLabel?: "question" | "answer" | undefined;
962
+ replaceLineBreakTokens?: boolean | undefined;
963
+ removeEmDashes?: boolean | undefined;
964
+ normalizeWhitespace?: boolean | undefined;
965
+ maxLength?: number | undefined;
966
+ ellipsis?: string | undefined;
967
+ fallbackWithParent?: string | undefined;
968
+ fallbackWithoutParent?: string | undefined;
969
+ fallbackBySlug?: Record<string, string> | undefined;
970
+ } | undefined;
971
+ description?: {
972
+ source?: "content" | "fallback" | undefined;
973
+ fallback?: string | undefined;
974
+ stripLeadingLabel?: "question" | "answer" | undefined;
975
+ replaceLineBreakTokens?: boolean | undefined;
976
+ removeEmDashes?: boolean | undefined;
977
+ normalizeWhitespace?: boolean | undefined;
978
+ maxLength?: number | undefined;
979
+ ellipsis?: string | undefined;
980
+ fallbackWithParent?: string | undefined;
981
+ fallbackWithoutParent?: string | undefined;
982
+ fallbackBySlug?: Record<string, string> | undefined;
983
+ } | undefined;
984
+ fallback?: {
985
+ title?: string | undefined;
986
+ description?: string | undefined;
987
+ ogImage?: string | undefined;
988
+ ogImageAlt?: string | undefined;
989
+ noindex?: boolean | undefined;
990
+ nofollow?: boolean | undefined;
991
+ } | undefined;
992
+ useFirstBodyImage?: boolean | undefined;
993
+ useTermImage?: boolean | undefined;
994
+ imageAltSource?: "title" | "content" | undefined;
995
+ legacyImageSource?: "legacy-thumbnail" | undefined;
996
+ imageAllowedOrigins?: string[] | undefined;
997
+ legacyImageAllowedOrigins?: string[] | undefined;
998
+ normalizeCloudflareImages?: boolean | undefined;
999
+ }, {
1000
+ title?: {
1001
+ source?: "content" | "fallback" | undefined;
1002
+ fallback?: string | undefined;
1003
+ stripLeadingLabel?: "question" | "answer" | undefined;
1004
+ replaceLineBreakTokens?: boolean | undefined;
1005
+ removeEmDashes?: boolean | undefined;
1006
+ normalizeWhitespace?: boolean | undefined;
1007
+ maxLength?: number | undefined;
1008
+ ellipsis?: string | undefined;
1009
+ fallbackWithParent?: string | undefined;
1010
+ fallbackWithoutParent?: string | undefined;
1011
+ fallbackBySlug?: Record<string, string> | undefined;
1012
+ } | undefined;
1013
+ description?: {
1014
+ source?: "content" | "fallback" | undefined;
1015
+ fallback?: string | undefined;
1016
+ stripLeadingLabel?: "question" | "answer" | undefined;
1017
+ replaceLineBreakTokens?: boolean | undefined;
1018
+ removeEmDashes?: boolean | undefined;
1019
+ normalizeWhitespace?: boolean | undefined;
1020
+ maxLength?: number | undefined;
1021
+ ellipsis?: string | undefined;
1022
+ fallbackWithParent?: string | undefined;
1023
+ fallbackWithoutParent?: string | undefined;
1024
+ fallbackBySlug?: Record<string, string> | undefined;
1025
+ } | undefined;
1026
+ fallback?: {
1027
+ title?: string | undefined;
1028
+ description?: string | undefined;
1029
+ ogImage?: string | undefined;
1030
+ ogImageAlt?: string | undefined;
1031
+ noindex?: boolean | undefined;
1032
+ nofollow?: boolean | undefined;
1033
+ } | undefined;
1034
+ useFirstBodyImage?: boolean | undefined;
1035
+ useTermImage?: boolean | undefined;
1036
+ imageAltSource?: "title" | "content" | undefined;
1037
+ legacyImageSource?: "legacy-thumbnail" | undefined;
1038
+ imageAllowedOrigins?: string[] | undefined;
1039
+ legacyImageAllowedOrigins?: string[] | undefined;
1040
+ normalizeCloudflareImages?: boolean | undefined;
1041
+ }>, {
1042
+ title?: {
1043
+ source?: "content" | "fallback" | undefined;
1044
+ fallback?: string | undefined;
1045
+ stripLeadingLabel?: "question" | "answer" | undefined;
1046
+ replaceLineBreakTokens?: boolean | undefined;
1047
+ removeEmDashes?: boolean | undefined;
1048
+ normalizeWhitespace?: boolean | undefined;
1049
+ maxLength?: number | undefined;
1050
+ ellipsis?: string | undefined;
1051
+ fallbackWithParent?: string | undefined;
1052
+ fallbackWithoutParent?: string | undefined;
1053
+ fallbackBySlug?: Record<string, string> | undefined;
1054
+ } | undefined;
1055
+ description?: {
1056
+ source?: "content" | "fallback" | undefined;
1057
+ fallback?: string | undefined;
1058
+ stripLeadingLabel?: "question" | "answer" | undefined;
1059
+ replaceLineBreakTokens?: boolean | undefined;
1060
+ removeEmDashes?: boolean | undefined;
1061
+ normalizeWhitespace?: boolean | undefined;
1062
+ maxLength?: number | undefined;
1063
+ ellipsis?: string | undefined;
1064
+ fallbackWithParent?: string | undefined;
1065
+ fallbackWithoutParent?: string | undefined;
1066
+ fallbackBySlug?: Record<string, string> | undefined;
1067
+ } | undefined;
1068
+ fallback?: {
1069
+ title?: string | undefined;
1070
+ description?: string | undefined;
1071
+ ogImage?: string | undefined;
1072
+ ogImageAlt?: string | undefined;
1073
+ noindex?: boolean | undefined;
1074
+ nofollow?: boolean | undefined;
1075
+ } | undefined;
1076
+ useFirstBodyImage?: boolean | undefined;
1077
+ useTermImage?: boolean | undefined;
1078
+ imageAltSource?: "title" | "content" | undefined;
1079
+ legacyImageSource?: "legacy-thumbnail" | undefined;
1080
+ imageAllowedOrigins?: string[] | undefined;
1081
+ legacyImageAllowedOrigins?: string[] | undefined;
1082
+ normalizeCloudflareImages?: boolean | undefined;
1083
+ }, {
1084
+ title?: {
1085
+ source?: "content" | "fallback" | undefined;
1086
+ fallback?: string | undefined;
1087
+ stripLeadingLabel?: "question" | "answer" | undefined;
1088
+ replaceLineBreakTokens?: boolean | undefined;
1089
+ removeEmDashes?: boolean | undefined;
1090
+ normalizeWhitespace?: boolean | undefined;
1091
+ maxLength?: number | undefined;
1092
+ ellipsis?: string | undefined;
1093
+ fallbackWithParent?: string | undefined;
1094
+ fallbackWithoutParent?: string | undefined;
1095
+ fallbackBySlug?: Record<string, string> | undefined;
1096
+ } | undefined;
1097
+ description?: {
1098
+ source?: "content" | "fallback" | undefined;
1099
+ fallback?: string | undefined;
1100
+ stripLeadingLabel?: "question" | "answer" | undefined;
1101
+ replaceLineBreakTokens?: boolean | undefined;
1102
+ removeEmDashes?: boolean | undefined;
1103
+ normalizeWhitespace?: boolean | undefined;
1104
+ maxLength?: number | undefined;
1105
+ ellipsis?: string | undefined;
1106
+ fallbackWithParent?: string | undefined;
1107
+ fallbackWithoutParent?: string | undefined;
1108
+ fallbackBySlug?: Record<string, string> | undefined;
1109
+ } | undefined;
1110
+ fallback?: {
1111
+ title?: string | undefined;
1112
+ description?: string | undefined;
1113
+ ogImage?: string | undefined;
1114
+ ogImageAlt?: string | undefined;
1115
+ noindex?: boolean | undefined;
1116
+ nofollow?: boolean | undefined;
1117
+ } | undefined;
1118
+ useFirstBodyImage?: boolean | undefined;
1119
+ useTermImage?: boolean | undefined;
1120
+ imageAltSource?: "title" | "content" | undefined;
1121
+ legacyImageSource?: "legacy-thumbnail" | undefined;
1122
+ imageAllowedOrigins?: string[] | undefined;
1123
+ legacyImageAllowedOrigins?: string[] | undefined;
1124
+ normalizeCloudflareImages?: boolean | undefined;
1125
+ }>;
1126
+ type MetadataDefaultRules = z.infer<typeof MetadataDefaultRulesSchema>;
1127
+ interface MetadataDefaultsDeclaration {
1128
+ posts?: {
1129
+ modelKeys?: string[];
1130
+ titleTemplates?: Record<string, string>;
1131
+ defaultRules?: Record<string, MetadataDefaultRules>;
1132
+ };
1133
+ terms?: {
1134
+ modelKeys?: string[];
1135
+ titleTemplates?: Record<string, string>;
1136
+ defaultRules?: Record<string, MetadataDefaultRules>;
1137
+ };
1138
+ }
1139
+ interface MetadataDefaultsInput {
1140
+ kind: "posts" | "terms";
1141
+ modelKey: string;
1142
+ title: string;
1143
+ description?: string | null;
1144
+ slug?: string;
1145
+ parentId?: string | null;
1146
+ featuredImage?: string | null;
1147
+ firstBodyImage?: string | null;
1148
+ legacyImage?: string | null;
1149
+ /** Current public site origin, used by the historical image adapter's origin check. */
1150
+ imageBaseUrl?: string;
1151
+ }
1152
+ /** Keep the customer's existing CF Images /lg behavior without rewriting unrelated origins. */
1153
+ declare function metadataContentImageUrl(value: string, normalizeCloudflareImages?: boolean): string;
1154
+ /** Receives automatic source values only. User-entered SEO never passes through cleanup/truncation. */
1155
+ declare function formatMetadataDefaults(input: MetadataDefaultsInput, declaration: MetadataDefaultsDeclaration): MetadataValues;
1156
+
1157
+ /** 검색 관리의 등록·검토·공개 Proxy가 공유하는 정확 경로 계약. */
1158
+ type NormalizedRedirectSourceResult = {
1159
+ readonly ok: true;
1160
+ readonly value: string;
1161
+ } | {
1162
+ readonly ok: false;
1163
+ readonly code: "invalid_source_path";
1164
+ };
1165
+ type NormalizedRedirectTargetResult = {
1166
+ readonly ok: true;
1167
+ readonly value: string;
1168
+ readonly kind: "internal" | "external";
1169
+ } | {
1170
+ readonly ok: false;
1171
+ readonly code: "invalid_target";
1172
+ };
1173
+ declare function normalizeRedirectPath(raw: string): string;
1174
+ /** 등록 제한과 Proxy의 자체 차단은 이 함수를 공유한다. */
1175
+ declare function isProtectedRedirectPath(path: string): boolean;
1176
+ declare function normalizeRedirectSource(raw: string): NormalizedRedirectSourceResult;
1177
+ declare function normalizeRedirectTarget(raw: string): NormalizedRedirectTargetResult;
1178
+
1179
+ export { BLOCK_NAME_PATTERN, type BindingResolver, type Block, type BlockBinding, type BlockDefinition, type BlockRegistry, CMS_FONT_SIZES, CMS_IMAGE_WIDTHS, CMS_LINE_HEIGHTS, CMS_PARAGRAPH_SPACINGS, type CategoryTreeEntry, type CategoryTreeEntryCategory, type CategoryTreePresentation, type CategoryTreeTerm, type ClientHydrationSpec, DEFAULT_SITE_PATTERN_PRESENTATION, EMPTY_SITE_PATTERN_PLACEMENTS, type EmbedProvider, FIELD_BINDING_SOURCE, FIELD_BINDING_SOURCE_ALIAS, type FaqEntry, IMAGE_ALT_MAX_LENGTH, INTERNAL_CONTENT_LINK_CLASS, INTERNAL_CONTENT_LINK_PENDING_ATTR, INTERNAL_CONTENT_LINK_PENDING_CLASS, INTERNAL_CONTENT_LINK_TOKEN_SOURCE, type InternalContentLinkResolver, type InternalContentLinkToken, LEGACY_BLOG_DETAIL_PATH, METADATA_FIELDS, type MetadataDefaultRules, MetadataDefaultRulesSchema, type MetadataDefaultsDeclaration, type MetadataDefaultsInput, type MetadataField, MetadataFieldSchema, type MetadataPatch, MetadataPatchSchema, type MetadataResolutionInput, type MetadataRobotsPolicy, MetadataRobotsPolicySchema, type MetadataTarget, type MetadataTargetKind, MetadataTargetKindSchema, type MetadataTextRule, MetadataTextRuleSchema, type MetadataValues, MetadataValuesSchema, type NormalizedEmbed, type NormalizedRedirectSourceResult, type NormalizedRedirectTargetResult, PHASE_1_CORE_BLOCKS, PHASE_1_CSP, POST_FOOTER_SLOT, type PatternSlots, type Phase1CoreBlockName, type PreviewTokenPayload, type PublicPathContext, type PublicPathPost, type PublicPathPresentation, type PublicRouteMetadata, type RoutablePost, type RouteCollection, SITE_PATTERN_BUTTON_COLORS_MAX, SITE_PATTERN_KEY_PATTERN, SITE_PATTERN_PLACEMENTS_KEY, SITE_PATTERN_SLOTS, type SectionLock, type SectionLockViolation, type SectionLockViolationCode, type SitePatternLayout, type SitePatternLinkStyle, type SitePatternPlacementRule, type SitePatternPlacements, type SitePatternPresentation, type SitePatternSlotKey, applyBlockBindings, bindingSrcValue, bindingTextValue, blockSchema, boundFieldValue, chainResolvers, cmsFontSize, cmsImageAlign, cmsImageStyle, cmsImageWidth, cmsLineHeight, cmsParagraphSpacing, createFieldBindingResolver, emptyPatternSlots, ensureImportedHtmlDocumentRoots, ensureStableIds, extractFaqEntries, faqPageJsonLd, findInternalContentLinkTokens, findSectionLockViolations, findSitePatternPlacementRule, formatMetadataDefaults, formatSectionLockViolations, htmlToPlainText, injectStableIdsTree, internalContentKeyFromPath, internalContentLinkResolverFrom, internalContentPathIndex, isAllowedEmbedSrc, isAllowedMapEmbedSrc, isInCollectionMode, isProtectedRedirectPath, isSectionContentPropPath, isSitePatternSlotKey, isValidBlock, isValidSitePatternKey, issuePreviewToken, mergeMetadataPatch, metadataContentImageUrl, normalizeEmbed, normalizeHexColor, normalizeImageAlt, normalizeRedirectPath, normalizeRedirectSource, normalizeRedirectTarget, parseBlock, postsForCollection, postsInAnyCollection, postsNotInAnyCollection, readMetadataValues, readSitePatternPlacements, readSitePatternPresentation, referencedSitePatternKeys, renderInternalContentLinksInHtml, renderInternalContentLinksInText, resolveCategoryPath, resolveCategoryTreeChain, resolveCategoryTreeEntryPath, resolveCategoryTreeHubPaths, resolveCategoryTreeSelection, resolveMetadata, resolvePatternSlots, resolvePostCategorySlug, resolvePostCollection, resolvePostPath, resolvePostPublicPath, resolvePostUrl, sanitizeHtml, sanitizeImportedCss, sanitizeImportedHtml, scopeImportedCss, serializeBlock, setSitePatternPlacementRule, sitePatternButtonColor, sitePatternPresentationAttributes, validateCollections, verifyPreviewToken };