@sonordev/site-kit 7.0.1 → 7.1.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 +3606 -0
- package/README.md +12 -13
- package/agent-manifest.json +11 -5
- package/dist/{AnalyticsProvider-EMM2TKRE.js → AnalyticsProvider-ZMQUV33M.js} +4 -4
- package/dist/{ArticleViewTracker-RA64BGL6.js → ArticleViewTracker-V7NUXYBY.js} +3 -3
- package/dist/{BlocksPopup-D25RFNOV.js → BlocksPopup-52EU7OUY.js} +4 -4
- package/dist/{ChatWidget-RYI7BMJJ.js → ChatWidget-5BHMNR57.js} +5 -5
- package/dist/{EngageWidget-UKFCN33M.js → EngageWidget-PCGLX7SO.js} +4 -4
- package/dist/{FileField-MUHA7LZR.js → FileField-TSFGNAMY.js} +3 -3
- package/dist/{FormSpotlight-TCLPWPLL.js → FormSpotlight-XLBWEOTE.js} +1 -1
- package/dist/{FormStage-CNYLP6I6.js → FormStage-IJQ5Q2X6.js} +1 -1
- package/dist/{ManagedForm-7ZL5SKTO.js → ManagedForm-Z3PKOPIZ.js} +6 -6
- package/dist/{ManagedNewsletterForm-33B4JLX7.js → ManagedNewsletterForm-QAO3POLC.js} +4 -4
- package/dist/{SignalCore-L5FVDHFE.js → SignalCore-RBA3VDBL.js} +3 -3
- package/dist/{SiteDesignReporter-4JOFL4FP.js → SiteDesignReporter-C4LR5X2V.js} +5 -5
- package/dist/SitemapSync-XVMGKCF3.js +8 -0
- package/dist/_client/booking-widget.js +5 -5
- package/dist/affiliates/index.js +3 -3
- package/dist/analytics/index.js +4 -4
- package/dist/articles/index.js +1 -1
- package/dist/articles/server-ui.js +1 -1
- package/dist/chat/index.js +5 -5
- package/dist/{chunk-FYBZ5SNP.js → chunk-3G2SE2J4.js} +1 -1
- package/dist/{chunk-HGCK465A.js → chunk-3J2ERO3I.js} +1 -1
- package/dist/{chunk-KXPBMCFL.js → chunk-3QI26673.js} +3 -1
- package/dist/{chunk-BMO3VGMR.js → chunk-3XPJKZ6D.js} +30 -7
- package/dist/{chunk-QGHSMJKW.js → chunk-4JQQDCMO.js} +1 -1
- package/dist/{chunk-6HDT4G4A.js → chunk-4YTYGG2C.js} +2 -2
- package/dist/{chunk-N2UVOR3X.js → chunk-662ILEZ6.js} +2 -0
- package/dist/chunk-6G43IRWR.js +4 -0
- package/dist/{chunk-LVESVYCE.js → chunk-7MHHWZKC.js} +11 -117
- package/dist/{chunk-MV2MBTC3.js → chunk-7QTMMHUO.js} +1 -1
- package/dist/{chunk-KPAZG65P.js → chunk-CGWUXUYZ.js} +138 -46
- package/dist/{chunk-4IQ52CXL.js → chunk-DUAO4Q75.js} +2 -2
- package/dist/{chunk-4RMVXRBO.js → chunk-EIULXXUJ.js} +3 -3
- package/dist/{chunk-3KUUH2YP.js → chunk-EVFZ7KEW.js} +1 -1
- package/dist/{chunk-OFOAHPUV.js → chunk-F42R35NV.js} +1 -1
- package/dist/{chunk-QANVUXKH.js → chunk-FLR3EMK6.js} +1 -1
- package/dist/{chunk-P4GRY6QP.js → chunk-GIAOPEN6.js} +1 -1
- package/dist/{chunk-P5J7VMQ3.js → chunk-GWUKQ26F.js} +1 -1
- package/dist/{chunk-TT63HHIT.js → chunk-HAG4YIZY.js} +1 -1
- package/dist/{chunk-QZZIKMAT.js → chunk-HVH37YPX.js} +1 -1
- package/dist/{chunk-SSUQKA7L.js → chunk-J4D6ZXRW.js} +1 -1
- package/dist/{chunk-GYESATRY.js → chunk-L2DJD5Y4.js} +1 -1
- package/dist/{chunk-WATH55UY.js → chunk-LFXVE32I.js} +1 -1
- package/dist/chunk-LPH5FANE.js +169 -0
- package/dist/{chunk-V6LSQRTH.js → chunk-PLUP2KN5.js} +1 -1
- package/dist/chunk-RYVDGXC2.js +19 -0
- package/dist/{chunk-EGOD74PP.js → chunk-U35H2JIQ.js} +2 -2
- package/dist/chunk-VCJYLYJV.js +49 -0
- package/dist/{chunk-FL4EPUWA.js → chunk-W2CL2DB3.js} +2 -2
- package/dist/{chunk-UZN4ZYR2.js → chunk-XD3ZQET6.js} +1 -1
- package/dist/{chunk-CVTVNC2U.js → chunk-XNVSCQ2O.js} +2 -2
- package/dist/{chunk-T3MC4HOD.js → chunk-YLSEB32F.js} +1 -1
- package/dist/chunk-ZETJTCMV.js +118 -0
- package/dist/{chunk-5SEM2V4A.js → chunk-ZIMFQWGJ.js} +3 -3
- package/dist/client/index.js +3 -3
- package/dist/cms/CmsPage.d.ts +1 -0
- package/dist/cms/CmsPreview.d.ts +1 -0
- package/dist/cms/CmsSection.d.ts +1 -0
- package/dist/cms/index.d.ts +6 -0
- package/dist/cms/server-api.d.ts +3 -0
- package/dist/commerce/index.js +4 -4
- package/dist/config/index.js +1 -1
- package/dist/contracts/entries.d.ts +1 -1
- package/dist/contracts/site-cache.d.ts +55 -0
- package/dist/contracts/site-edit-param.d.ts +7 -0
- package/dist/contracts/site-edit.d.ts +77 -0
- package/dist/contracts/slot-content.d.ts +111 -0
- package/dist/contracts/slots.d.ts +39 -25
- package/dist/engage/index.js +6 -6
- package/dist/fleet/index.js +4 -4
- package/dist/forms/index.js +8 -8
- package/dist/forms/server.js +2 -2
- package/dist/forms/types.d.ts +3 -1
- package/dist/images/index.js +4 -4
- package/dist/index.js +1 -1
- package/dist/layout/client.js +8 -7
- package/dist/layout/index.js +9 -8
- package/dist/llms/index.js +4 -2
- package/dist/llms/seo-revalidate.d.ts +8 -1
- package/dist/maps/index.js +3 -3
- package/dist/mcp/sonor.js +6 -6
- package/dist/overlay-RXV6U6QC.js +353 -0
- package/dist/proxy/index.js +2 -2
- package/dist/proxy/securityHeaders.d.ts +4 -0
- package/dist/revalidate/index.d.ts +44 -0
- package/dist/revalidate/index.js +27 -0
- package/dist/seo/ManagedContent.d.ts +2 -0
- package/dist/seo/client.js +4 -4
- package/dist/seo/index.js +9 -8
- package/dist/seo/llms.js +4 -2
- package/dist/seo/register-sitemap-cli.js +1 -1
- package/dist/seo/server.js +3 -2
- package/dist/seo/sitemap.js +2 -2
- package/dist/server/index.js +2 -2
- package/dist/{server-api-GJJQZVG7.js → server-api-BVCBLJKL.js} +2 -1
- package/dist/shared/build-entries.d.ts +1 -0
- package/dist/shared/edit-bridge.d.ts +8 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +2 -2
- package/dist/sitemap/index.js +2 -2
- package/dist/slots/ManagedLink.d.ts +31 -0
- package/dist/slots/ManagedList.d.ts +30 -0
- package/dist/slots/ManagedRichText.d.ts +31 -0
- package/dist/slots/contract.js +2 -1
- package/dist/slots/edit/locate.d.ts +30 -0
- package/dist/slots/edit/overlay.d.ts +18 -0
- package/dist/slots/index.d.ts +12 -4
- package/dist/slots/index.js +4 -2
- package/dist/slots/revalidate.d.ts +8 -3
- package/dist/slots/rich.d.ts +7 -0
- package/dist/slots/server-api.d.ts +6 -2
- package/dist/sync/index.js +5 -5
- package/dist/website/images.js +4 -4
- package/dist/website/index.js +5 -5
- package/dist/website/popups.js +4 -4
- package/dist/website/slots/contract.js +2 -1
- package/dist/website/slots.js +4 -2
- package/dist/{writeLLMsTxt-UMHKGNRR.js → writeLLMsTxt-QR23OQUE.js} +1 -1
- package/docs/MIGRATING-TO-7.md +146 -0
- package/docs.json +69 -0
- package/package.json +14 -4
- package/src/admin-auth/README.md +88 -0
- package/src/analytics/README.md +264 -0
- package/src/articles/README.md +325 -0
- package/src/commerce/README.md +109 -0
- package/src/cta-bar/README.md +154 -0
- package/src/engage/README.md +241 -0
- package/src/forms/README.md +219 -0
- package/src/images/README.md +74 -0
- package/src/layout/README.md +66 -0
- package/src/llms/README.md +723 -0
- package/src/mcp/README.md +376 -0
- package/src/motion/README.md +372 -0
- package/src/og/README.md +304 -0
- package/src/proxy/README.md +152 -0
- package/src/redirects/README.md +74 -0
- package/src/reputation/README.md +64 -0
- package/src/revalidate/README.md +82 -0
- package/src/seo/README.md +346 -0
- package/src/signal/README.md +115 -0
- package/src/sitemap/README.md +127 -0
- package/src/slots/README.md +168 -0
- package/src/sync/README.md +115 -0
- package/dist/SitemapSync-7WKY4HXI.js +0 -8
- package/dist/chunk-SS636UDN.js +0 -35
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { SITE_EDIT_PARAM } from './chunk-6G43IRWR.js';
|
|
2
|
+
import { parseSlotRichText } from './chunk-LPH5FANE.js';
|
|
3
|
+
import './chunk-PKBMQBKP.js';
|
|
4
|
+
|
|
5
|
+
// src/contracts/site-edit.ts
|
|
6
|
+
var SITE_EDIT_VERSION = 1;
|
|
7
|
+
var SONOR_APP_ORIGIN = "https://app.sonor.io";
|
|
8
|
+
function isSonorAppOrigin(origin) {
|
|
9
|
+
if (origin === SONOR_APP_ORIGIN) return true;
|
|
10
|
+
try {
|
|
11
|
+
const url = new URL(origin);
|
|
12
|
+
return url.protocol === "http:" && (url.hostname === "localhost" || url.hostname === "127.0.0.1");
|
|
13
|
+
} catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
var SONOR_TO_SITE = /* @__PURE__ */ new Set(["sonor-edit:slots", "sonor-edit:select", "sonor-edit:preview", "sonor-edit:reload"]);
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
function parseSonorToSiteMessage(data) {
|
|
22
|
+
if (!isRecord(data) || typeof data.type !== "string" || !SONOR_TO_SITE.has(data.type)) return null;
|
|
23
|
+
switch (data.type) {
|
|
24
|
+
case "sonor-edit:slots":
|
|
25
|
+
return Array.isArray(data.slots) ? { type: data.type, slots: data.slots.filter(isEditableSlot).slice(0, 500) } : null;
|
|
26
|
+
case "sonor-edit:select":
|
|
27
|
+
return data.key === null || typeof data.key === "string" ? { type: data.type, key: data.key } : null;
|
|
28
|
+
case "sonor-edit:preview":
|
|
29
|
+
return typeof data.key === "string" ? {
|
|
30
|
+
type: data.type,
|
|
31
|
+
key: data.key,
|
|
32
|
+
...typeof data.content === "string" || data.content === null ? { content: data.content } : {},
|
|
33
|
+
...isRecord(data.value) || data.value === null ? { value: data.value } : {}
|
|
34
|
+
} : null;
|
|
35
|
+
default:
|
|
36
|
+
return { type: "sonor-edit:reload" };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function isEditableSlot(value) {
|
|
40
|
+
return isRecord(value) && typeof value.key === "string" && typeof value.id === "string" && typeof value.type === "string" && (typeof value.content === "string" || value.content === null);
|
|
41
|
+
}
|
|
42
|
+
function normalizeEditText(text) {
|
|
43
|
+
return text.replace(/\s+/g, " ").trim();
|
|
44
|
+
}
|
|
45
|
+
function slotNeedles(slot) {
|
|
46
|
+
const clean = (values) => values.map((v) => normalizeEditText(v ?? "")).filter((v) => v.length > 0);
|
|
47
|
+
switch (slot.type) {
|
|
48
|
+
case "link": {
|
|
49
|
+
const value = slot.value;
|
|
50
|
+
return clean([value?.label ?? slot.content]);
|
|
51
|
+
}
|
|
52
|
+
case "list": {
|
|
53
|
+
const value = slot.value;
|
|
54
|
+
const items = value?.items ?? [];
|
|
55
|
+
return items.length ? clean(items.map((item) => item.title || item.body)) : clean((slot.content ?? "").split("\n"));
|
|
56
|
+
}
|
|
57
|
+
case "rich": {
|
|
58
|
+
const first = parseSlotRichText(slot.content ?? "")[0];
|
|
59
|
+
if (!first) return [];
|
|
60
|
+
const inline = first.t === "p" ? first.c : first.items[0] ?? [];
|
|
61
|
+
return clean([inlineText(inline)]);
|
|
62
|
+
}
|
|
63
|
+
default:
|
|
64
|
+
return clean([slot.content]);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function inlineText(nodes) {
|
|
68
|
+
return nodes.map((n) => n.t === "text" ? n.v : n.t === "br" ? " " : inlineText(n.c)).join("");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/slots/edit/locate.ts
|
|
72
|
+
var SKIPPED = /* @__PURE__ */ new Set(["SCRIPT", "STYLE", "NOSCRIPT", "TEMPLATE", "TITLE", "HEAD", "svg"]);
|
|
73
|
+
function isSkipped(el) {
|
|
74
|
+
for (let node = el; node; node = node.parentElement) {
|
|
75
|
+
if (SKIPPED.has(node.tagName) || node.hasAttribute("data-sonor-edit-ui")) return true;
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
function textNodes(root) {
|
|
80
|
+
const doc = root.ownerDocument;
|
|
81
|
+
const walker = doc.createTreeWalker(
|
|
82
|
+
root,
|
|
83
|
+
4
|
|
84
|
+
/* NodeFilter.SHOW_TEXT */
|
|
85
|
+
);
|
|
86
|
+
const out = [];
|
|
87
|
+
for (let node = walker.nextNode(); node; node = walker.nextNode()) {
|
|
88
|
+
const text = node;
|
|
89
|
+
if (text.data.trim() && !isSkipped(text.parentElement)) out.push(text);
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
function findByText(root, needle, claimed) {
|
|
94
|
+
if (!needle) return null;
|
|
95
|
+
for (const node of textNodes(root)) {
|
|
96
|
+
const parent = node.parentElement;
|
|
97
|
+
if (parent && !claimed.has(parent) && normalizeEditText(node.data) === needle) {
|
|
98
|
+
return { element: parent, textNode: node };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
let best = null;
|
|
102
|
+
for (const el of Array.from(root.querySelectorAll("*"))) {
|
|
103
|
+
if (claimed.has(el) || isSkipped(el)) continue;
|
|
104
|
+
if (normalizeEditText(el.textContent ?? "") !== needle) continue;
|
|
105
|
+
if (!best || best.contains(el)) best = el;
|
|
106
|
+
}
|
|
107
|
+
return best ? { element: best } : null;
|
|
108
|
+
}
|
|
109
|
+
function commonAncestor(elements) {
|
|
110
|
+
const [first, ...rest] = elements;
|
|
111
|
+
for (let node = first ?? null; node; node = node.parentElement) {
|
|
112
|
+
if (rest.every((el) => node.contains(el))) return node;
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
function hrefMatches(anchor, href) {
|
|
117
|
+
const raw = anchor.getAttribute("href") ?? "";
|
|
118
|
+
if (raw === href) return true;
|
|
119
|
+
try {
|
|
120
|
+
const base = anchor.ownerDocument.location?.href ?? "http://localhost/";
|
|
121
|
+
return new URL(raw, base).href === new URL(href, base).href;
|
|
122
|
+
} catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function locateSlot(root, slot, claimed) {
|
|
127
|
+
const needles = slotNeedles(slot);
|
|
128
|
+
if (!needles.length) return null;
|
|
129
|
+
if (slot.type === "link") {
|
|
130
|
+
const href = slot.value?.href;
|
|
131
|
+
const anchors = Array.from(root.querySelectorAll("a")).filter(
|
|
132
|
+
(a) => !claimed.has(a) && !isSkipped(a) && normalizeEditText(a.textContent ?? "") === needles[0]
|
|
133
|
+
);
|
|
134
|
+
const anchor = href && anchors.find((a) => hrefMatches(a, href)) || anchors[0];
|
|
135
|
+
return anchor ? { key: slot.key, element: anchor } : null;
|
|
136
|
+
}
|
|
137
|
+
if (slot.type === "list") {
|
|
138
|
+
const items = [];
|
|
139
|
+
const local = new Set(claimed);
|
|
140
|
+
for (const needle of needles) {
|
|
141
|
+
const hit2 = findByText(root, needle, local);
|
|
142
|
+
if (hit2) {
|
|
143
|
+
items.push(hit2.element);
|
|
144
|
+
local.add(hit2.element);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (!items.length) return null;
|
|
148
|
+
const element = items.length > 1 ? commonAncestor(items) : items[0].parentElement;
|
|
149
|
+
return element && !claimed.has(element) ? { key: slot.key, element } : null;
|
|
150
|
+
}
|
|
151
|
+
const hit = findByText(root, needles[0], claimed);
|
|
152
|
+
if (!hit) return null;
|
|
153
|
+
if (slot.type === "rich") {
|
|
154
|
+
const blocks = (slot.content ?? "").split(/\n\s*\n/).filter((b) => b.trim()).length;
|
|
155
|
+
const element = blocks > 1 && hit.element.parentElement ? hit.element.parentElement : hit.element;
|
|
156
|
+
return { key: slot.key, element };
|
|
157
|
+
}
|
|
158
|
+
return { key: slot.key, element: hit.element, textNode: hit.textNode };
|
|
159
|
+
}
|
|
160
|
+
function locateSlots(root, slots) {
|
|
161
|
+
const claimed = /* @__PURE__ */ new Set();
|
|
162
|
+
const located = [];
|
|
163
|
+
const ordered = [...slots].sort(
|
|
164
|
+
(a, b) => (slotNeedles(b)[0]?.length ?? 0) - (slotNeedles(a)[0]?.length ?? 0)
|
|
165
|
+
);
|
|
166
|
+
for (const slot of ordered) {
|
|
167
|
+
const hit = locateSlot(root, slot, claimed);
|
|
168
|
+
if (hit) {
|
|
169
|
+
claimed.add(hit.element);
|
|
170
|
+
located.push(hit);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return located;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/slots/edit/overlay.ts
|
|
177
|
+
var ATTR = "data-sonor-edit";
|
|
178
|
+
var SELECTED = "data-sonor-edit-selected";
|
|
179
|
+
var STYLES = `
|
|
180
|
+
[${ATTR}] { outline: 2px dashed rgba(99, 102, 241, 0.7); outline-offset: 3px; cursor: pointer; border-radius: 2px; }
|
|
181
|
+
[${ATTR}]:hover { outline-style: solid; }
|
|
182
|
+
[${SELECTED}] { outline: 3px solid rgb(99, 102, 241) !important; outline-offset: 3px; }
|
|
183
|
+
`;
|
|
184
|
+
function framingOrigin(win) {
|
|
185
|
+
const ancestors = win.location.ancestorOrigins;
|
|
186
|
+
const candidate = ancestors?.length ? ancestors[0] : safeOrigin(win.document.referrer);
|
|
187
|
+
return candidate && isSonorAppOrigin(candidate) ? candidate : null;
|
|
188
|
+
}
|
|
189
|
+
function safeOrigin(url) {
|
|
190
|
+
try {
|
|
191
|
+
return url ? new URL(url).origin : null;
|
|
192
|
+
} catch {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function withEditParam(href, base) {
|
|
197
|
+
try {
|
|
198
|
+
const url = new URL(href, base);
|
|
199
|
+
if (url.origin !== new URL(base).origin) return null;
|
|
200
|
+
url.searchParams.set(SITE_EDIT_PARAM, "1");
|
|
201
|
+
return url.toString();
|
|
202
|
+
} catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function renderInline(doc, nodes, parent) {
|
|
207
|
+
for (const node of nodes) {
|
|
208
|
+
if (node.t === "text") parent.appendChild(doc.createTextNode(node.v));
|
|
209
|
+
else if (node.t === "br") parent.appendChild(doc.createElement("br"));
|
|
210
|
+
else {
|
|
211
|
+
const el = doc.createElement(node.t === "link" ? "a" : node.t);
|
|
212
|
+
if (node.t === "link") el.setAttribute("href", node.href);
|
|
213
|
+
renderInline(doc, node.c, el);
|
|
214
|
+
parent.appendChild(el);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function renderBlocks(doc, blocks, parent) {
|
|
219
|
+
for (const block of blocks) {
|
|
220
|
+
if (block.t === "p") {
|
|
221
|
+
const p = doc.createElement("p");
|
|
222
|
+
renderInline(doc, block.c, p);
|
|
223
|
+
parent.appendChild(p);
|
|
224
|
+
} else {
|
|
225
|
+
const list = doc.createElement(block.t);
|
|
226
|
+
for (const item of block.items) {
|
|
227
|
+
const li = doc.createElement("li");
|
|
228
|
+
renderInline(doc, item, li);
|
|
229
|
+
list.appendChild(li);
|
|
230
|
+
}
|
|
231
|
+
parent.appendChild(list);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function startEditOverlay(win = window) {
|
|
236
|
+
const origin = framingOrigin(win);
|
|
237
|
+
if (!origin) return () => {
|
|
238
|
+
};
|
|
239
|
+
const doc = win.document;
|
|
240
|
+
let slots = [];
|
|
241
|
+
let located = [];
|
|
242
|
+
const originals = /* @__PURE__ */ new Map();
|
|
243
|
+
const style = doc.createElement("style");
|
|
244
|
+
style.setAttribute("data-sonor-edit-ui", "");
|
|
245
|
+
style.textContent = STYLES;
|
|
246
|
+
doc.head.appendChild(style);
|
|
247
|
+
const post = (message) => win.parent.postMessage(message, origin);
|
|
248
|
+
const path = () => win.location.pathname;
|
|
249
|
+
const clearMarks = () => {
|
|
250
|
+
for (const el of Array.from(doc.querySelectorAll(`[${ATTR}]`))) {
|
|
251
|
+
el.removeAttribute(ATTR);
|
|
252
|
+
el.removeAttribute(SELECTED);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
const locate = () => {
|
|
256
|
+
clearMarks();
|
|
257
|
+
located = locateSlots(doc.body, slots);
|
|
258
|
+
for (const hit of located) hit.element.setAttribute(ATTR, hit.key);
|
|
259
|
+
post({ type: "sonor-edit:found", path: path(), found: located.map((l) => l.key) });
|
|
260
|
+
};
|
|
261
|
+
const select = (key) => {
|
|
262
|
+
for (const el of Array.from(doc.querySelectorAll(`[${SELECTED}]`))) el.removeAttribute(SELECTED);
|
|
263
|
+
const hit = key ? located.find((l) => l.key === key) : void 0;
|
|
264
|
+
if (!hit) return;
|
|
265
|
+
hit.element.setAttribute(SELECTED, "");
|
|
266
|
+
hit.element.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
267
|
+
};
|
|
268
|
+
const preview = (key, content, value) => {
|
|
269
|
+
const hit = located.find((l) => l.key === key);
|
|
270
|
+
const slot = slots.find((s) => s.key === key);
|
|
271
|
+
if (!hit || !slot) return;
|
|
272
|
+
const el = hit.element;
|
|
273
|
+
if (!originals.has(key)) {
|
|
274
|
+
originals.set(key, {
|
|
275
|
+
html: el.innerHTML,
|
|
276
|
+
text: hit.textNode?.data,
|
|
277
|
+
href: el instanceof HTMLAnchorElement ? el.getAttribute("href") : void 0
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
const before = originals.get(key);
|
|
281
|
+
if (content === null && value === null) {
|
|
282
|
+
if (hit.textNode && before.text !== void 0) hit.textNode.data = before.text;
|
|
283
|
+
else if (before.html !== void 0) el.innerHTML = before.html;
|
|
284
|
+
if (before.href !== void 0 && before.href !== null) el.setAttribute("href", before.href);
|
|
285
|
+
originals.delete(key);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (slot.type === "text" && typeof content === "string") {
|
|
289
|
+
if (hit.textNode) hit.textNode.data = content;
|
|
290
|
+
else el.textContent = content;
|
|
291
|
+
} else if (slot.type === "rich" && typeof content === "string") {
|
|
292
|
+
const blocks = parseSlotRichText(content);
|
|
293
|
+
el.replaceChildren();
|
|
294
|
+
if (blocks.length === 1 && blocks[0].t === "p" && el.tagName !== "DIV") renderInline(doc, blocks[0].c, el);
|
|
295
|
+
else renderBlocks(doc, blocks, el);
|
|
296
|
+
} else if (slot.type === "link" && value && typeof value === "object") {
|
|
297
|
+
const link = value;
|
|
298
|
+
if (typeof link.label === "string") el.textContent = link.label;
|
|
299
|
+
if (typeof link.href === "string" && el instanceof HTMLAnchorElement) el.setAttribute("href", link.href);
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
const onMessage = (event) => {
|
|
303
|
+
if (event.origin !== origin || event.source !== win.parent) return;
|
|
304
|
+
const message = parseSonorToSiteMessage(event.data);
|
|
305
|
+
if (!message) return;
|
|
306
|
+
switch (message.type) {
|
|
307
|
+
case "sonor-edit:slots":
|
|
308
|
+
slots = message.slots;
|
|
309
|
+
originals.clear();
|
|
310
|
+
locate();
|
|
311
|
+
break;
|
|
312
|
+
case "sonor-edit:select":
|
|
313
|
+
select(message.key);
|
|
314
|
+
break;
|
|
315
|
+
case "sonor-edit:preview":
|
|
316
|
+
preview(message.key, message.content, message.value);
|
|
317
|
+
break;
|
|
318
|
+
case "sonor-edit:reload":
|
|
319
|
+
win.location.reload();
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
const onClick = (event) => {
|
|
324
|
+
const target = event.target;
|
|
325
|
+
if (!target || typeof target.closest !== "function") return;
|
|
326
|
+
const hit = located.find((l) => l.element === target || l.element.contains(target));
|
|
327
|
+
if (hit) {
|
|
328
|
+
event.preventDefault();
|
|
329
|
+
event.stopPropagation();
|
|
330
|
+
select(hit.key);
|
|
331
|
+
post({ type: "sonor-edit:select", key: hit.key });
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const anchor = target.closest("a");
|
|
335
|
+
const href = anchor?.getAttribute("href");
|
|
336
|
+
if (!anchor || !href || anchor.target === "_blank" || href.startsWith("#")) return;
|
|
337
|
+
const next = withEditParam(href, win.location.href);
|
|
338
|
+
event.preventDefault();
|
|
339
|
+
event.stopPropagation();
|
|
340
|
+
if (next) win.location.assign(next);
|
|
341
|
+
};
|
|
342
|
+
win.addEventListener("message", onMessage);
|
|
343
|
+
doc.addEventListener("click", onClick, true);
|
|
344
|
+
post({ type: "sonor-edit:ready", version: SITE_EDIT_VERSION, path: path(), title: doc.title });
|
|
345
|
+
return () => {
|
|
346
|
+
win.removeEventListener("message", onMessage);
|
|
347
|
+
doc.removeEventListener("click", onClick, true);
|
|
348
|
+
clearMarks();
|
|
349
|
+
style.remove();
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export { framingOrigin, startEditOverlay, withEditParam };
|
package/dist/proxy/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { buildSecurityHeaders } from '../chunk-
|
|
2
|
-
export { DEFAULT_FRAME_ANCESTORS } from '../chunk-
|
|
1
|
+
import { buildSecurityHeaders } from '../chunk-3QI26673.js';
|
|
2
|
+
export { DEFAULT_FRAME_ANCESTORS } from '../chunk-3QI26673.js';
|
|
3
3
|
import { handleManagedRedirects } from '../chunk-HXJ54KAM.js';
|
|
4
4
|
import { buildAiDiscoveryHeaders, wantsLlmsDiscoveryLink } from '../chunk-PO2TRJPY.js';
|
|
5
5
|
import '../chunk-Z22QVHT4.js';
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
* Labs case studies embed three live client frames each; without this
|
|
20
20
|
* entry every one of them is refused with ERR_BLOCKED_BY_RESPONSE.
|
|
21
21
|
*
|
|
22
|
+
* app.sonor.io frames the live site for Edit on page (Sonor → Website →
|
|
23
|
+
* Content). The page is public anyway, and the overlay it loads there only
|
|
24
|
+
* outlines copy and reports clicks (`slots/edit/overlay.ts`).
|
|
25
|
+
*
|
|
22
26
|
* upforgeapps.com is deliberately NOT here. It is a third Upforge apex,
|
|
23
27
|
* but it only *links* to case studies (`upforge.io/work/<slug>`, see its
|
|
24
28
|
* `lib/proof.ts`) and frames no client site anywhere. An origin earns a
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sonordev/site-kit/revalidate — the route Sonor calls when content changes.
|
|
3
|
+
*
|
|
4
|
+
* A site caches its pages and every fetch from Sonor. When someone edits
|
|
5
|
+
* content in Sonor (copy, metadata, an article, a portfolio item), Sonor POSTs
|
|
6
|
+
* the paths and cache tags that changed to this route, authenticated with the
|
|
7
|
+
* project's API key, and only those pages regenerate. Pages stay cached until
|
|
8
|
+
* something changes, and an edit is live in seconds.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* // app/api/seo-revalidate/route.ts
|
|
13
|
+
* export { POST } from '@sonordev/site-kit/revalidate'
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* A site with a publication (articles) passes where it lives, so the index
|
|
17
|
+
* and feeds refresh with each article:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { createRevalidateRoute } from '@sonordev/site-kit/revalidate'
|
|
21
|
+
* export const POST = createRevalidateRoute({ publicationBasePath: '/insights' })
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* Built on `createSeoRevalidationHandler` (`../llms/seo-revalidate`), the
|
|
25
|
+
* single implementation of the webhook; this only supplies the key and
|
|
26
|
+
* Next's cache functions.
|
|
27
|
+
*/
|
|
28
|
+
import { type SeoRevalidationHandlerOptions } from '../llms/seo-revalidate';
|
|
29
|
+
export { SITE_CACHE_TAGS, SITE_REVALIDATE_PATH, isSiteRevalidatePong } from '../contracts/site-cache';
|
|
30
|
+
export type { SiteCacheTag, SiteRevalidatePayload, SiteRevalidatePong } from '../contracts/site-cache';
|
|
31
|
+
export type RevalidateRouteOptions = Pick<SeoRevalidationHandlerOptions, 'publicationBasePath' | 'extraPaths' | 'extendPayload'> & {
|
|
32
|
+
/** The key Sonor signs the call with. Defaults to `SONOR_API_KEY`, read on every call. */
|
|
33
|
+
secret?: SeoRevalidationHandlerOptions['secret'];
|
|
34
|
+
};
|
|
35
|
+
type NextCache = Pick<typeof import('next/cache'), 'revalidatePath' | 'revalidateTag'>;
|
|
36
|
+
/**
|
|
37
|
+
* A POST handler for the revalidation route. Options are checked when it's
|
|
38
|
+
* created, so a bad `publicationBasePath` fails the build, not the webhook.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createRevalidateRoute(options?: RevalidateRouteOptions,
|
|
41
|
+
/** For tests and non-Next frameworks. Defaults to `next/cache`. */
|
|
42
|
+
loadCache?: () => Promise<NextCache>): (request: Request) => Promise<Response>;
|
|
43
|
+
/** The revalidation route for a site without a publication. */
|
|
44
|
+
export declare const POST: (request: Request) => Promise<Response>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createSeoRevalidationHandler } from '../chunk-7MHHWZKC.js';
|
|
2
|
+
import '../chunk-XTRZGXB2.js';
|
|
3
|
+
export { SITE_CACHE_TAGS, SITE_REVALIDATE_PATH, isSiteRevalidatePong } from '../chunk-RYVDGXC2.js';
|
|
4
|
+
import '../chunk-4JQQDCMO.js';
|
|
5
|
+
import '../chunk-PKBMQBKP.js';
|
|
6
|
+
|
|
7
|
+
// src/revalidate/index.ts
|
|
8
|
+
function createRevalidateRoute(options = {}, loadCache = () => import('next/cache.js')) {
|
|
9
|
+
const { secret = () => process.env.SONOR_API_KEY, ...rest } = options;
|
|
10
|
+
createSeoRevalidationHandler({ ...rest, secret, revalidatePath: () => {
|
|
11
|
+
}, revalidateTag: () => {
|
|
12
|
+
} });
|
|
13
|
+
return async (request) => {
|
|
14
|
+
const { revalidatePath, revalidateTag } = await loadCache();
|
|
15
|
+
return createSeoRevalidationHandler({
|
|
16
|
+
...rest,
|
|
17
|
+
secret,
|
|
18
|
+
revalidatePath,
|
|
19
|
+
// Next 16.3 takes a profile as the second argument; { expire: 0 } makes
|
|
20
|
+
// the next visitor get the new version rather than one last stale page.
|
|
21
|
+
revalidateTag
|
|
22
|
+
})(request);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
var POST = createRevalidateRoute();
|
|
26
|
+
|
|
27
|
+
export { POST, createRevalidateRoute };
|
|
@@ -6,7 +6,9 @@ import type { ManagedContentProps, ManagedContentBlock } from './types';
|
|
|
6
6
|
* Useful when you need to access the raw data. `site` is the sub-site host
|
|
7
7
|
* override for multi-site projects; it resolves from NEXT_PUBLIC_SITE_URL when
|
|
8
8
|
* omitted.
|
|
9
|
+
* @deprecated Since 7.1. Content blocks are retired in favour of managed copy: use `<ManagedRichText>` from `@sonordev/site-kit/website/slots`. Removed in 8.0.
|
|
9
10
|
*/
|
|
10
11
|
export declare function getManagedContentData(path: string, section: string, site?: string): Promise<ManagedContentBlock | null>;
|
|
12
|
+
/** @deprecated Since 7.1. Content blocks are retired in favour of managed copy: use `<ManagedRichText>` from `@sonordev/site-kit/website/slots`. Removed in 8.0. */
|
|
11
13
|
export declare function ManagedContent(props: ManagedContentProps): React.ReactElement;
|
|
12
14
|
export default ManagedContent;
|
package/dist/seo/client.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { SitemapSync } from '../chunk-
|
|
2
|
+
export { SitemapSync } from '../chunk-LFXVE32I.js';
|
|
3
3
|
import '../chunk-YVKRYQRG.js';
|
|
4
4
|
import '../chunk-43OCZ3JA.js';
|
|
5
5
|
import '../chunk-EKBEOXTH.js';
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import '../chunk-
|
|
8
|
-
import '../chunk-
|
|
6
|
+
import '../chunk-U35H2JIQ.js';
|
|
7
|
+
import '../chunk-EVFZ7KEW.js';
|
|
8
|
+
import '../chunk-4JQQDCMO.js';
|
|
9
9
|
import '../chunk-PKBMQBKP.js';
|
package/dist/seo/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export { ManagedNoScripts, ManagedScripts } from '../chunk-MVLMXC44.js';
|
|
2
2
|
import { pickManagedLlmSchemaForJsonLd } from '../chunk-4Y5FWDPM.js';
|
|
3
3
|
import { safeJsonLd } from '../chunk-4KZ6W3ZH.js';
|
|
4
|
-
export { SitemapSync } from '../chunk-
|
|
5
|
-
import { getManagedMetadata } from '../chunk-
|
|
6
|
-
export { generateSitemap, getABVariant, getManagedMetadata, getManagedMetadataWithAB, getRedirect, getRobotsDirective, isIndexable } from '../chunk-
|
|
7
|
-
import { getContentBlock, getSchemaMarkups, getSEOPageData, getEntityEnhancedSchema, getFAQData, getInternalLinks, getEntities, pruneSchemaTypes } from '../chunk-
|
|
8
|
-
export { getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from '../chunk-
|
|
4
|
+
export { SitemapSync } from '../chunk-LFXVE32I.js';
|
|
5
|
+
import { getManagedMetadata } from '../chunk-4YTYGG2C.js';
|
|
6
|
+
export { generateSitemap, getABVariant, getManagedMetadata, getManagedMetadataWithAB, getRedirect, getRobotsDirective, isIndexable } from '../chunk-4YTYGG2C.js';
|
|
7
|
+
import { getContentBlock, getSchemaMarkups, getSEOPageData, getEntityEnhancedSchema, getFAQData, getInternalLinks, getEntities, pruneSchemaTypes } from '../chunk-662ILEZ6.js';
|
|
8
|
+
export { getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from '../chunk-662ILEZ6.js';
|
|
9
9
|
import '../chunk-BQR4IPBW.js';
|
|
10
|
+
import '../chunk-RYVDGXC2.js';
|
|
10
11
|
import '../chunk-MJP63SSS.js';
|
|
11
12
|
import '../chunk-X6F6SO4S.js';
|
|
12
13
|
import '../chunk-MH2DSGC6.js';
|
|
@@ -16,9 +17,9 @@ import '../chunk-FESKKJAS.js';
|
|
|
16
17
|
import '../chunk-A4CC4ZG3.js';
|
|
17
18
|
import '../chunk-43OCZ3JA.js';
|
|
18
19
|
import '../chunk-EKBEOXTH.js';
|
|
19
|
-
import '../chunk-
|
|
20
|
-
import '../chunk-
|
|
21
|
-
import '../chunk-
|
|
20
|
+
import '../chunk-U35H2JIQ.js';
|
|
21
|
+
import '../chunk-EVFZ7KEW.js';
|
|
22
|
+
import '../chunk-4JQQDCMO.js';
|
|
22
23
|
import '../chunk-PKBMQBKP.js';
|
|
23
24
|
import { Suspense } from 'react';
|
|
24
25
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
package/dist/seo/llms.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { createLLMsFullTxtHandler, createLLMsTxtHandler, formatSourcedFactsSection, llmsResponseHeaders } from '../chunk-ZETJTCMV.js';
|
|
2
2
|
export { buildAiDiscoveryHeaders, wantsLlmsDiscoveryLink } from '../chunk-PO2TRJPY.js';
|
|
3
3
|
export { AI_RETRIEVAL_CRAWLERS, AI_TRAINING_CRAWLERS, buildAiCrawlerRules, createRobotsTxtHandler } from '../chunk-QLTDFUJ7.js';
|
|
4
|
+
export { LEGACY_PUBLICATION_PATH, SEO_REVALIDATION_MAX_BODY_BYTES, SEO_REVALIDATION_MAX_ITEMS, createLlmsRevalidateHandler, createSeoRevalidationHandler, parseSeoRevalidationPayload } from '../chunk-7MHHWZKC.js';
|
|
4
5
|
import '../chunk-XTRZGXB2.js';
|
|
5
6
|
export { AEOBlock, AEOCitedContent, AEOClaim, AEOComparison, AEODefinition, AEOEntity, AEOProvenanceList, AEOStep, AEOSteps, AEOSummary, DEFAULT_SPEAKABLE_SELECTORS, SpeakableSchema, createSpeakableSchema, getSpeakableSelectorsForPage } from '../chunk-PSAG45YF.js';
|
|
6
|
-
export { AGENT_ACCESS_HEADING, appendAgentAccessSection, describesMcp, detectMcpServer, formatAgentAccessSection, generateLLMsFullTxt, generateLLMsTxt, writeLLMsTxtToPublic } from '../chunk-
|
|
7
|
+
export { AGENT_ACCESS_HEADING, appendAgentAccessSection, describesMcp, detectMcpServer, formatAgentAccessSection, generateLLMsFullTxt, generateLLMsTxt, writeLLMsTxtToPublic } from '../chunk-J4D6ZXRW.js';
|
|
7
8
|
export { getBusinessInfo, getFAQItems, getLLMsData, getOptimizedLLMsTxt, getPageSummaries, getServices } from '../chunk-GLHQ3LRO.js';
|
|
8
9
|
import '../chunk-L5UOHS6E.js';
|
|
9
10
|
import '../chunk-WMVK77ND.js';
|
|
@@ -14,4 +15,5 @@ import '../chunk-MJP63SSS.js';
|
|
|
14
15
|
import '../chunk-YVKRYQRG.js';
|
|
15
16
|
import '../chunk-FESKKJAS.js';
|
|
16
17
|
import '../chunk-A4CC4ZG3.js';
|
|
18
|
+
import '../chunk-4JQQDCMO.js';
|
|
17
19
|
import '../chunk-PKBMQBKP.js';
|
|
@@ -458,7 +458,7 @@ async function registerLocalSitemap(options) {
|
|
|
458
458
|
}
|
|
459
459
|
if (options.writeLlms && result.success) {
|
|
460
460
|
try {
|
|
461
|
-
const { writeLLMsTxtToPublic } = await import('../writeLLMsTxt-
|
|
461
|
+
const { writeLLMsTxtToPublic } = await import('../writeLLMsTxt-QR23OQUE.js');
|
|
462
462
|
const written = await writeLLMsTxtToPublic({
|
|
463
463
|
// Resolved here too: the sync's own `site` is scoped to the branch that
|
|
464
464
|
// posts, and this runs on the skip path as well.
|
package/dist/seo/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { generateSitemap, getManagedMetadata, getManagedMetadataWithAB, registerLocalSitemap } from '../chunk-
|
|
2
|
-
export { getABTest, getContentBlock, getFAQData, getInternalLinks, getManagedScripts, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, recordABImpression, registerSitemap } from '../chunk-
|
|
1
|
+
export { generateSitemap, getManagedMetadata, getManagedMetadataWithAB, registerLocalSitemap } from '../chunk-4YTYGG2C.js';
|
|
2
|
+
export { getABTest, getContentBlock, getFAQData, getInternalLinks, getManagedScripts, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, recordABImpression, registerSitemap } from '../chunk-662ILEZ6.js';
|
|
3
3
|
import '../chunk-BQR4IPBW.js';
|
|
4
|
+
import '../chunk-RYVDGXC2.js';
|
|
4
5
|
import '../chunk-MJP63SSS.js';
|
|
5
6
|
import '../chunk-X6F6SO4S.js';
|
|
6
7
|
import '../chunk-MH2DSGC6.js';
|
package/dist/seo/sitemap.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { createSitemap, getPortfolioPaths, syncSitemapToPortal } from '../chunk-
|
|
1
|
+
export { createSitemap, getPortfolioPaths, syncSitemapToPortal } from '../chunk-HAG4YIZY.js';
|
|
2
2
|
import '../chunk-Z22QVHT4.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-J4D6ZXRW.js';
|
|
4
4
|
import '../chunk-GLHQ3LRO.js';
|
|
5
5
|
import '../chunk-L5UOHS6E.js';
|
|
6
6
|
import '../chunk-WMVK77ND.js';
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { resolveClientCredential } from '../chunk-
|
|
1
|
+
export { resolveClientCredential } from '../chunk-F42R35NV.js';
|
|
2
2
|
import '../chunk-VX5CMNMM.js';
|
|
3
3
|
export { requireServerApiConfig, resolveApiOrigin, resolveServerApiConfig, serverApiFetch } from '../chunk-X6F6SO4S.js';
|
|
4
4
|
import '../chunk-MH2DSGC6.js';
|
|
5
|
-
import '../chunk-
|
|
5
|
+
import '../chunk-4JQQDCMO.js';
|
|
6
6
|
import '../chunk-PKBMQBKP.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { ensureMetadata, getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from './chunk-
|
|
1
|
+
export { ensureMetadata, getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap } from './chunk-662ILEZ6.js';
|
|
2
|
+
import './chunk-RYVDGXC2.js';
|
|
2
3
|
import './chunk-MJP63SSS.js';
|
|
3
4
|
import './chunk-X6F6SO4S.js';
|
|
4
5
|
import './chunk-MH2DSGC6.js';
|
|
@@ -98,6 +98,7 @@ export declare const entry: {
|
|
|
98
98
|
readonly 'slots/index': 'src/slots/index.ts';
|
|
99
99
|
/** Pure contract + HMAC signing (src/contracts; sonor-api imports @sonordev/contracts/slots) */
|
|
100
100
|
readonly 'slots/contract': 'src/slots/contract.ts';
|
|
101
|
+
readonly 'revalidate/index': 'src/revalidate/index.ts';
|
|
101
102
|
readonly 'website/index': 'src/website/index.ts';
|
|
102
103
|
/** Pure contract: design tokens, popup blocks, the text sanitizer */
|
|
103
104
|
readonly 'website/contract': 'src/website/contract.ts';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Starts Sonor's "Edit on page" overlay when, and only when, the Sonor
|
|
3
|
+
* dashboard frames this page with `?sonor_edit`. Every other visitor pays
|
|
4
|
+
* one query-string check; the overlay itself (`slots/edit/overlay.ts`) is a
|
|
5
|
+
* separate chunk imported on demand. Runs after load, so the page has
|
|
6
|
+
* hydrated before the overlay looks for its copy.
|
|
7
|
+
*/
|
|
8
|
+
export declare function startEditBridge(): () => void;
|
package/dist/shared/version.d.ts
CHANGED
package/dist/signal/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { useSignalExperiment, useSignalEvent } from '../chunk-
|
|
3
|
-
export { SignalBridge, useSignal, useSignalConfig, useSignalEvent, useSignalExperiment, useSignalOutcome } from '../chunk-
|
|
2
|
+
import { useSignalExperiment, useSignalEvent } from '../chunk-HVH37YPX.js';
|
|
3
|
+
export { SignalBridge, useSignal, useSignalConfig, useSignalEvent, useSignalExperiment, useSignalOutcome } from '../chunk-HVH37YPX.js';
|
|
4
4
|
import '../chunk-PKBMQBKP.js';
|
|
5
5
|
import React, { useEffect } from 'react';
|
|
6
6
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
package/dist/sitemap/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { createSitemap, getPortfolioPaths, syncSitemapToPortal } from '../chunk-
|
|
1
|
+
export { createSitemap, getPortfolioPaths, syncSitemapToPortal } from '../chunk-HAG4YIZY.js';
|
|
2
2
|
import '../chunk-Z22QVHT4.js';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-J4D6ZXRW.js';
|
|
4
4
|
import '../chunk-GLHQ3LRO.js';
|
|
5
5
|
import '../chunk-L5UOHS6E.js';
|
|
6
6
|
import '../chunk-WMVK77ND.js';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type SlotLinkValue } from './contract';
|
|
3
|
+
import type { SlotResolveOptions } from './server-api';
|
|
4
|
+
export interface ManagedLinkProps extends Omit<SlotResolveOptions, 'fallback' | 'type' | 'fallbackValue'> {
|
|
5
|
+
/** Stable slot id, e.g. "home-hero-cta". */
|
|
6
|
+
id: string;
|
|
7
|
+
/** The static destination. */
|
|
8
|
+
href: string;
|
|
9
|
+
/** The static label. */
|
|
10
|
+
label: string;
|
|
11
|
+
/**
|
|
12
|
+
* Draw the link yourself (a Next `<Link>`, a button style). Called with the
|
|
13
|
+
* managed `{ label, href }`, or the static ones when nothing's managed.
|
|
14
|
+
* Without it, ManagedLink renders a plain `<a>` with `className`.
|
|
15
|
+
*/
|
|
16
|
+
children?: (link: SlotLinkValue) => React.ReactNode;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* ManagedLink — a call to action whose label and destination Sonor manages.
|
|
21
|
+
* Server component, fallback-first and signature-verified like ManagedSlot.
|
|
22
|
+
* Managed hrefs are limited to https, http, mailto, tel, #anchor and /paths.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <ManagedLink id="home-hero-cta" href="/contact" label="Get a free quote">
|
|
27
|
+
* {({ href, label }) => <Link href={href} className="btn">{label}</Link>}
|
|
28
|
+
* </ManagedLink>
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function ManagedLink({ id, href, label, children, className, site, revalidate, page, }: ManagedLinkProps): Promise<React.ReactElement>;
|