@roottale/cms-core 0.61.1 → 0.63.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 +21 -0
- package/dist/index.cjs +244 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +241 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -595,4 +595,21 @@ declare function cmsImageStyle(attrs: Record<string, unknown>): {
|
|
|
595
595
|
height?: string | undefined;
|
|
596
596
|
};
|
|
597
597
|
|
|
598
|
-
|
|
598
|
+
interface SectionLock {
|
|
599
|
+
move?: boolean;
|
|
600
|
+
remove?: boolean;
|
|
601
|
+
structure?: boolean;
|
|
602
|
+
}
|
|
603
|
+
type SectionLockViolationCode = "locked_section_inserted" | "locked_section_removed" | "locked_section_moved" | "locked_section_lock_changed" | "locked_section_structure_changed";
|
|
604
|
+
interface SectionLockViolation {
|
|
605
|
+
code: SectionLockViolationCode;
|
|
606
|
+
sectionId: string;
|
|
607
|
+
sectionType: string;
|
|
608
|
+
field: string;
|
|
609
|
+
}
|
|
610
|
+
declare function isSectionContentPropPath(sectionType: string, path: readonly (string | number)[]): boolean;
|
|
611
|
+
/** 고객 콘텐츠 저장 경계. 기존 lock 플래그와 무관하게 제작 구조를 보호한다. */
|
|
612
|
+
declare function findSectionLockViolations(beforeDoc: unknown, afterDoc: unknown): SectionLockViolation[];
|
|
613
|
+
declare function formatSectionLockViolations(violations: readonly SectionLockViolation[]): string;
|
|
614
|
+
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -595,4 +595,21 @@ declare function cmsImageStyle(attrs: Record<string, unknown>): {
|
|
|
595
595
|
height?: string | undefined;
|
|
596
596
|
};
|
|
597
597
|
|
|
598
|
-
|
|
598
|
+
interface SectionLock {
|
|
599
|
+
move?: boolean;
|
|
600
|
+
remove?: boolean;
|
|
601
|
+
structure?: boolean;
|
|
602
|
+
}
|
|
603
|
+
type SectionLockViolationCode = "locked_section_inserted" | "locked_section_removed" | "locked_section_moved" | "locked_section_lock_changed" | "locked_section_structure_changed";
|
|
604
|
+
interface SectionLockViolation {
|
|
605
|
+
code: SectionLockViolationCode;
|
|
606
|
+
sectionId: string;
|
|
607
|
+
sectionType: string;
|
|
608
|
+
field: string;
|
|
609
|
+
}
|
|
610
|
+
declare function isSectionContentPropPath(sectionType: string, path: readonly (string | number)[]): boolean;
|
|
611
|
+
/** 고객 콘텐츠 저장 경계. 기존 lock 플래그와 무관하게 제작 구조를 보호한다. */
|
|
612
|
+
declare function findSectionLockViolations(beforeDoc: unknown, afterDoc: unknown): SectionLockViolation[];
|
|
613
|
+
declare function formatSectionLockViolations(violations: readonly SectionLockViolation[]): string;
|
|
614
|
+
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -1600,6 +1600,244 @@ function cmsImageStyle(attrs) {
|
|
|
1600
1600
|
} : {}
|
|
1601
1601
|
};
|
|
1602
1602
|
}
|
|
1603
|
+
|
|
1604
|
+
// src/section-locks.ts
|
|
1605
|
+
var CONTENT_PROP_PATHS = {
|
|
1606
|
+
hero: [
|
|
1607
|
+
["eyebrow"],
|
|
1608
|
+
["title"],
|
|
1609
|
+
["description"],
|
|
1610
|
+
["imageSrc"],
|
|
1611
|
+
["imageAlt"],
|
|
1612
|
+
["cta", "label"],
|
|
1613
|
+
["cta", "href"]
|
|
1614
|
+
],
|
|
1615
|
+
"rich-text": [["heading"], ["body"]],
|
|
1616
|
+
services: [
|
|
1617
|
+
["heading"],
|
|
1618
|
+
["description"],
|
|
1619
|
+
["items", Number.NaN, "title"],
|
|
1620
|
+
["items", Number.NaN, "description"],
|
|
1621
|
+
["items", Number.NaN, "href"]
|
|
1622
|
+
],
|
|
1623
|
+
faq: [
|
|
1624
|
+
["heading"],
|
|
1625
|
+
["items", Number.NaN, "question"],
|
|
1626
|
+
["items", Number.NaN, "answer"]
|
|
1627
|
+
],
|
|
1628
|
+
"cta-banner": [["title"], ["description"], ["cta", "label"], ["cta", "href"]],
|
|
1629
|
+
"blog-list": [["heading"], ["emptyMessage"]],
|
|
1630
|
+
"lead-form": [["heading"], ["description"], ["submitLabel"]],
|
|
1631
|
+
trust: [
|
|
1632
|
+
["heading"],
|
|
1633
|
+
["metrics", Number.NaN, "value"],
|
|
1634
|
+
["metrics", Number.NaN, "unit"],
|
|
1635
|
+
["metrics", Number.NaN, "label"],
|
|
1636
|
+
["metrics", Number.NaN, "source"],
|
|
1637
|
+
["credentials", Number.NaN, "name"],
|
|
1638
|
+
["credentials", Number.NaN, "issuer"],
|
|
1639
|
+
["credentials", Number.NaN, "kind"],
|
|
1640
|
+
["credentials", Number.NaN, "image"],
|
|
1641
|
+
["logos", Number.NaN, "src"],
|
|
1642
|
+
["logos", Number.NaN, "alt"],
|
|
1643
|
+
["logos", Number.NaN, "href"],
|
|
1644
|
+
["disclaimer"]
|
|
1645
|
+
],
|
|
1646
|
+
contact: [
|
|
1647
|
+
["heading"],
|
|
1648
|
+
["form", "enabled"],
|
|
1649
|
+
["phone"],
|
|
1650
|
+
["address"],
|
|
1651
|
+
["hours", Number.NaN, "day"],
|
|
1652
|
+
["hours", Number.NaN, "open"],
|
|
1653
|
+
["hours", Number.NaN, "close"],
|
|
1654
|
+
["hours", Number.NaN, "note"],
|
|
1655
|
+
["mapEmbedUrl"]
|
|
1656
|
+
],
|
|
1657
|
+
expertise: [
|
|
1658
|
+
["heading"],
|
|
1659
|
+
["description"],
|
|
1660
|
+
["items", Number.NaN, "label"],
|
|
1661
|
+
["items", Number.NaN, "kicker"],
|
|
1662
|
+
["items", Number.NaN, "title"],
|
|
1663
|
+
["items", Number.NaN, "body"],
|
|
1664
|
+
["items", Number.NaN, "imageSrc"],
|
|
1665
|
+
["items", Number.NaN, "imageAlt"],
|
|
1666
|
+
["items", Number.NaN, "tags", Number.NaN],
|
|
1667
|
+
["items", Number.NaN, "href"],
|
|
1668
|
+
["items", Number.NaN, "ctaLabel"]
|
|
1669
|
+
],
|
|
1670
|
+
spaces: [
|
|
1671
|
+
["heading"],
|
|
1672
|
+
["description"],
|
|
1673
|
+
["spaces", Number.NaN, "label"],
|
|
1674
|
+
["spaces", Number.NaN, "kicker"],
|
|
1675
|
+
["spaces", Number.NaN, "title"],
|
|
1676
|
+
["spaces", Number.NaN, "description"],
|
|
1677
|
+
["spaces", Number.NaN, "imageSrc"],
|
|
1678
|
+
["spaces", Number.NaN, "imageAlt"],
|
|
1679
|
+
["spaces", Number.NaN, "tags", Number.NaN],
|
|
1680
|
+
["disclaimer"]
|
|
1681
|
+
],
|
|
1682
|
+
concerns: [
|
|
1683
|
+
["heading"],
|
|
1684
|
+
["description"],
|
|
1685
|
+
["figureImage"],
|
|
1686
|
+
["figureAlt"],
|
|
1687
|
+
["regions", Number.NaN, "label"],
|
|
1688
|
+
["regions", Number.NaN, "title"],
|
|
1689
|
+
["regions", Number.NaN, "description"],
|
|
1690
|
+
["regions", Number.NaN, "items", Number.NaN],
|
|
1691
|
+
["regions", Number.NaN, "href"],
|
|
1692
|
+
["regions", Number.NaN, "ctaLabel"],
|
|
1693
|
+
["disclaimer"]
|
|
1694
|
+
]
|
|
1695
|
+
};
|
|
1696
|
+
function valueEquals(left, right) {
|
|
1697
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
1698
|
+
}
|
|
1699
|
+
function isRecord2(value) {
|
|
1700
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1701
|
+
}
|
|
1702
|
+
function collectChangedPaths(before, after, prefix = []) {
|
|
1703
|
+
if (valueEquals(before, after)) return [];
|
|
1704
|
+
if (Array.isArray(before) && Array.isArray(after)) {
|
|
1705
|
+
if (before.length !== after.length) return [prefix];
|
|
1706
|
+
return before.flatMap(
|
|
1707
|
+
(item, index) => collectChangedPaths(item, after[index], [...prefix, index])
|
|
1708
|
+
);
|
|
1709
|
+
}
|
|
1710
|
+
if ((isRecord2(before) || before == null) && (isRecord2(after) || after == null)) {
|
|
1711
|
+
const beforeRecord = isRecord2(before) ? before : {};
|
|
1712
|
+
const afterRecord = isRecord2(after) ? after : {};
|
|
1713
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(beforeRecord), ...Object.keys(afterRecord)]);
|
|
1714
|
+
if (keys.size === 0) return [prefix];
|
|
1715
|
+
return [...keys].flatMap(
|
|
1716
|
+
(key) => collectChangedPaths(beforeRecord[key], afterRecord[key], [...prefix, key])
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1719
|
+
return [prefix];
|
|
1720
|
+
}
|
|
1721
|
+
function contentPathMatches(pattern, path) {
|
|
1722
|
+
if (pattern.length !== path.length) return false;
|
|
1723
|
+
return pattern.every((segment, index) => {
|
|
1724
|
+
const actual = path[index];
|
|
1725
|
+
return Number.isNaN(segment) ? typeof actual === "number" : segment === actual;
|
|
1726
|
+
});
|
|
1727
|
+
}
|
|
1728
|
+
function isSectionContentPropPath(sectionType, path) {
|
|
1729
|
+
const patterns = CONTENT_PROP_PATHS[sectionType] ?? [];
|
|
1730
|
+
return patterns.some((pattern) => contentPathMatches(pattern, path));
|
|
1731
|
+
}
|
|
1732
|
+
function collectSectionSnapshots(doc) {
|
|
1733
|
+
const sections = [];
|
|
1734
|
+
function visit(node, path) {
|
|
1735
|
+
if (!isRecord2(node)) return;
|
|
1736
|
+
if (node.type === "section") {
|
|
1737
|
+
const attrs = isRecord2(node.attrs) ? node.attrs : {};
|
|
1738
|
+
sections.push({
|
|
1739
|
+
id: typeof attrs._id === "string" ? attrs._id : "",
|
|
1740
|
+
path,
|
|
1741
|
+
sectionType: typeof attrs.sectionType === "string" ? attrs.sectionType : "",
|
|
1742
|
+
attrs,
|
|
1743
|
+
props: attrs.props ?? {}
|
|
1744
|
+
});
|
|
1745
|
+
}
|
|
1746
|
+
if (Array.isArray(node.content)) {
|
|
1747
|
+
node.content.forEach((child, index) => visit(child, `${path}.${index}`));
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
visit(doc, "doc");
|
|
1751
|
+
return sections;
|
|
1752
|
+
}
|
|
1753
|
+
function findSectionLockViolations(beforeDoc, afterDoc) {
|
|
1754
|
+
const before = collectSectionSnapshots(beforeDoc);
|
|
1755
|
+
const after = collectSectionSnapshots(afterDoc);
|
|
1756
|
+
const afterById = new Map(after.map((section) => [section.id, section]));
|
|
1757
|
+
const beforeById = new Map(before.map((section) => [section.id, section]));
|
|
1758
|
+
const violations = [];
|
|
1759
|
+
for (const sections of [before, after]) {
|
|
1760
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1761
|
+
for (const section of sections) {
|
|
1762
|
+
if (!section.id || ids.has(section.id)) {
|
|
1763
|
+
violations.push({
|
|
1764
|
+
code: "locked_section_structure_changed",
|
|
1765
|
+
sectionId: section.id,
|
|
1766
|
+
sectionType: section.sectionType,
|
|
1767
|
+
field: "_id"
|
|
1768
|
+
});
|
|
1769
|
+
}
|
|
1770
|
+
ids.add(section.id);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
for (const section of before) {
|
|
1774
|
+
const next = afterById.get(section.id);
|
|
1775
|
+
if (!next) {
|
|
1776
|
+
violations.push({
|
|
1777
|
+
code: "locked_section_removed",
|
|
1778
|
+
sectionId: section.id,
|
|
1779
|
+
sectionType: section.sectionType,
|
|
1780
|
+
field: "(node)"
|
|
1781
|
+
});
|
|
1782
|
+
continue;
|
|
1783
|
+
}
|
|
1784
|
+
if (section.path !== next.path) {
|
|
1785
|
+
violations.push({
|
|
1786
|
+
code: "locked_section_moved",
|
|
1787
|
+
sectionId: section.id,
|
|
1788
|
+
sectionType: section.sectionType,
|
|
1789
|
+
field: "(index)"
|
|
1790
|
+
});
|
|
1791
|
+
}
|
|
1792
|
+
const fields = /* @__PURE__ */ new Set([
|
|
1793
|
+
...Object.keys(section.attrs),
|
|
1794
|
+
...Object.keys(next.attrs)
|
|
1795
|
+
]);
|
|
1796
|
+
fields.delete("props");
|
|
1797
|
+
for (const field of fields) {
|
|
1798
|
+
if (!valueEquals(section.attrs[field], next.attrs[field])) {
|
|
1799
|
+
violations.push({
|
|
1800
|
+
code: field === "lock" ? "locked_section_lock_changed" : "locked_section_structure_changed",
|
|
1801
|
+
sectionId: section.id,
|
|
1802
|
+
sectionType: section.sectionType,
|
|
1803
|
+
field
|
|
1804
|
+
});
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
for (const path of collectChangedPaths(section.props, next.props)) {
|
|
1808
|
+
if (!isSectionContentPropPath(section.sectionType, path)) {
|
|
1809
|
+
violations.push({
|
|
1810
|
+
code: "locked_section_structure_changed",
|
|
1811
|
+
sectionId: section.id,
|
|
1812
|
+
sectionType: section.sectionType,
|
|
1813
|
+
field: `props.${path.join(".") || "(root)"}`
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
for (const section of after) {
|
|
1819
|
+
if (beforeById.has(section.id)) continue;
|
|
1820
|
+
violations.push({
|
|
1821
|
+
code: "locked_section_inserted",
|
|
1822
|
+
sectionId: section.id,
|
|
1823
|
+
sectionType: section.sectionType,
|
|
1824
|
+
field: "(node)"
|
|
1825
|
+
});
|
|
1826
|
+
}
|
|
1827
|
+
return violations;
|
|
1828
|
+
}
|
|
1829
|
+
function formatSectionLockViolations(violations) {
|
|
1830
|
+
return violations.map((violation) => {
|
|
1831
|
+
const label = `${violation.sectionType || "section"} \uC139\uC158(${violation.sectionId})`;
|
|
1832
|
+
if (violation.code === "locked_section_inserted") return `${label} \uCD94\uAC00`;
|
|
1833
|
+
if (violation.code === "locked_section_removed") return `${label} \uC0AD\uC81C`;
|
|
1834
|
+
if (violation.code === "locked_section_moved") return `${label} \uC774\uB3D9`;
|
|
1835
|
+
if (violation.code === "locked_section_lock_changed") {
|
|
1836
|
+
return `${label} \uC7A0\uAE08 \uBCC0\uACBD`;
|
|
1837
|
+
}
|
|
1838
|
+
return `${label} \uAD6C\uC870 \uBCC0\uACBD(${violation.field})`;
|
|
1839
|
+
}).join(" / ");
|
|
1840
|
+
}
|
|
1603
1841
|
export {
|
|
1604
1842
|
BLOCK_NAME_PATTERN,
|
|
1605
1843
|
CMS_FONT_SIZES,
|
|
@@ -1642,7 +1880,9 @@ export {
|
|
|
1642
1880
|
extractFaqEntries,
|
|
1643
1881
|
faqPageJsonLd,
|
|
1644
1882
|
findInternalContentLinkTokens,
|
|
1883
|
+
findSectionLockViolations,
|
|
1645
1884
|
findSitePatternPlacementRule,
|
|
1885
|
+
formatSectionLockViolations,
|
|
1646
1886
|
htmlToPlainText,
|
|
1647
1887
|
injectStableIdsTree,
|
|
1648
1888
|
internalContentKeyFromPath,
|
|
@@ -1651,6 +1891,7 @@ export {
|
|
|
1651
1891
|
isAllowedEmbedSrc,
|
|
1652
1892
|
isAllowedMapEmbedSrc,
|
|
1653
1893
|
isInCollectionMode,
|
|
1894
|
+
isSectionContentPropPath,
|
|
1654
1895
|
isSitePatternSlotKey,
|
|
1655
1896
|
isValidBlock,
|
|
1656
1897
|
isValidSitePatternKey,
|