@sonordev/site-kit 8.2.0 → 8.3.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/AGENTS.md +13 -1
- package/CHANGELOG.md +5 -0
- package/README.md +9 -5
- package/agent-manifest.json +47 -8
- package/dist/{AnalyticsProvider-6TAA3XYB.js → AnalyticsProvider-QXO33JUF.js} +6 -6
- package/dist/{ArticleFaqSection-3Q26DP7P.js → ArticleFaqSection-DEWE5B4Q.js} +1 -1
- package/dist/{ArticleViewTracker-H4N7YCLC.js → ArticleViewTracker-KN6ENIRS.js} +17 -6
- package/dist/{BlocksPopup-FJT5YQD3.js → BlocksPopup-3RPN6YVJ.js} +6 -6
- package/dist/{ChatWidget-THQHHTAA.js → ChatWidget-D2X445PO.js} +6 -6
- package/dist/{FileField-OZXXJGUM.js → FileField-UNGSNGJ5.js} +4 -4
- package/dist/{FormSpotlight-MLDJS246.js → FormSpotlight-JFH2ENKQ.js} +1 -1
- package/dist/{FormStage-6RVY7M3R.js → FormStage-RC3WHHXP.js} +1 -1
- package/dist/{ManagedForm-3VV54RVH.js → ManagedForm-FOQZ2IYG.js} +7 -7
- package/dist/{ManagedNewsletterForm-RTJDGMGG.js → ManagedNewsletterForm-NFNF33V3.js} +16 -7
- package/dist/{SignalCore-T7ZOCA44.js → SignalCore-5KABGX5C.js} +4 -4
- package/dist/SiteChat-JQ46ZIJ4.js +6 -0
- package/dist/SiteDesignReporter-N7L6DR4J.js +12 -0
- package/dist/{SitePopups-K6ADAWFK.js → SitePopups-WZBKX5Q3.js} +6 -6
- package/dist/SitemapSync-GY6UADRI.js +9 -0
- package/dist/_client/booking-widget.js +6 -6
- package/dist/_client/testimonial-section.js +3 -3
- package/dist/affiliates/index.js +4 -4
- package/dist/analytics/index.js +6 -6
- package/dist/{article-styles-GFXJJDLE.js → article-styles-7QONZJR5.js} +3 -3
- package/dist/article-tables-6XHVULPU.js +2 -0
- package/dist/articles/Article.d.ts +2 -89
- package/dist/articles/ArticleFAQ.d.ts +2 -41
- package/dist/articles/ArticleFaqSection.d.ts +2 -2
- package/dist/articles/ArticleList.d.ts +2 -79
- package/dist/articles/ArticleViewTracker.d.ts +2 -15
- package/dist/articles/AuthorCard.d.ts +2 -10
- package/dist/articles/AuthorPage.d.ts +2 -8
- package/dist/articles/ClusterLandingPage.d.ts +2 -40
- package/dist/articles/ClusterNavigation.d.ts +2 -37
- package/dist/articles/ManagedNewsletterForm.d.ts +3 -12
- package/dist/articles/NewsletterShell.d.ts +2 -17
- package/dist/articles/NewsletterWidget.d.ts +2 -30
- package/dist/articles/PublicationLayout.d.ts +2 -67
- package/dist/articles/PublicationSidebar.d.ts +2 -36
- package/dist/articles/RelatedPosts.d.ts +2 -22
- package/dist/articles/ServiceCallout.d.ts +2 -56
- package/dist/articles/TableOfContents.d.ts +2 -6
- package/dist/articles/article-photos.d.ts +2 -9
- package/dist/articles/article-styles.d.ts +2 -21
- package/dist/articles/article-tables.d.ts +2 -12
- package/dist/articles/artwork.d.ts +2 -13
- package/dist/articles/author-schema.d.ts +2 -72
- package/dist/articles/author-social.d.ts +2 -14
- package/dist/articles/excerpt.d.ts +2 -17
- package/dist/articles/index.d.ts +2 -79
- package/dist/articles/index.js +16 -11
- package/dist/articles/news-sitemap.d.ts +2 -46
- package/dist/articles/processArticleHtml.d.ts +2 -34
- package/dist/articles/public-reads.d.ts +2 -26
- package/dist/articles/reading-time.d.ts +2 -9
- package/dist/articles/routes.d.ts +2 -52
- package/dist/articles/server-core.d.ts +2 -461
- package/dist/articles/server-ui.d.ts +2 -30
- package/dist/articles/server-ui.js +26 -17
- package/dist/articles/server.d.ts +2 -461
- package/dist/articles/server.js +14 -5
- package/dist/articles/types.d.ts +2 -316
- package/dist/articles/widget-styles.d.ts +2 -8
- package/dist/chat/index.js +8 -8
- package/dist/{chunk-575L73NT.js → chunk-2JMCBJM5.js} +1 -1
- package/dist/chunk-34ZYJTQR.js +1 -0
- package/dist/{chunk-7FSB2EXS.js → chunk-3OY52UFM.js} +1 -1
- package/dist/{chunk-WMVK77ND.js → chunk-4K735O3J.js} +1 -1
- package/dist/{chunk-66G47P5C.js → chunk-4PVMUPC6.js} +2 -2
- package/dist/{chunk-L5UOHS6E.js → chunk-5D7ZISUP.js} +1 -1
- package/dist/{chunk-SMYX3AAO.js → chunk-5RYSTKVU.js} +1 -1
- package/dist/{chunk-6CJGZFOU.js → chunk-A4MPHIVP.js} +1 -1
- package/dist/chunk-B7T2SFUF.js +1 -0
- package/dist/{chunk-FV2VD7WM.js → chunk-BC7JMY4Z.js} +3 -3
- package/dist/{chunk-57K4GW3D.js → chunk-BOCYBDKV.js} +1 -1
- package/dist/{chunk-NFRJTOTB.js → chunk-BSQP6PRA.js} +1 -1
- package/dist/{chunk-GKGSXUVQ.js → chunk-BVB5FBAA.js} +1 -1
- package/dist/{chunk-Q72M5KBS.js → chunk-C2UROFGZ.js} +1 -1
- package/dist/{chunk-3EU6S5YC.js → chunk-C4AFNZT2.js} +1 -1
- package/dist/{chunk-WACWV5EP.js → chunk-D6ZIQMHB.js} +3 -3
- package/dist/{chunk-GYF2ULVO.js → chunk-DJAYFHVF.js} +1 -1
- package/dist/{chunk-JC2VS2SB.js → chunk-DPSNMOMZ.js} +1 -1
- package/dist/{chunk-NNEIBXGU.js → chunk-E3UR37RX.js} +2 -2
- package/dist/{chunk-Y3INC4QJ.js → chunk-E4PTMORJ.js} +1 -1
- package/dist/{chunk-EBILJHUF.js → chunk-EA6FZMYA.js} +2 -2
- package/dist/{chunk-X7VKRHFF.js → chunk-FHUTOXS7.js} +1 -1
- package/dist/{chunk-JBEUZJS3.js → chunk-GKJVSZ7H.js} +3 -3
- package/dist/chunk-H72ZFO3F.js +1 -0
- package/dist/{chunk-FVXFLVXF.js → chunk-HND6BDXC.js} +3 -3
- package/dist/chunk-IEGDPRQB.js +14 -0
- package/dist/{chunk-CAH4Y4PY.js → chunk-JO76F5WP.js} +1 -1
- package/dist/{chunk-FQUGGPBM.js → chunk-KJVUOJMW.js} +58 -58
- package/dist/{chunk-SC4MZGWZ.js → chunk-LBDWAXAO.js} +1 -1
- package/dist/{chunk-WSNG2K3T.js → chunk-LPKKSYKX.js} +3 -3
- package/dist/{chunk-HUBMKTPW.js → chunk-M5SF7NCC.js} +1 -1
- package/dist/{chunk-YBAFUM3Z.js → chunk-MQ4REMTH.js} +2 -2
- package/dist/{chunk-BQZPHICL.js → chunk-NA4Z4CQG.js} +1 -1
- package/dist/{chunk-727R7C5R.js → chunk-OIWFXUVD.js} +2 -2
- package/dist/{chunk-H4R2GPAB.js → chunk-QBCWVT2S.js} +2 -2
- package/dist/{chunk-WYZ4OUON.js → chunk-QCZHYO5M.js} +1 -1
- package/dist/{chunk-I6QFPSUU.js → chunk-QDILCQBL.js} +9 -9
- package/dist/{chunk-WK3N3Y7V.js → chunk-SCTVADDL.js} +2 -2
- package/dist/{chunk-QXMIKDOL.js → chunk-SNRE3ZVZ.js} +3 -3
- package/dist/{chunk-WBC5B3JD.js → chunk-TT4JZDKM.js} +3 -3
- package/dist/{chunk-5ZCY36TY.js → chunk-U7Y3QG3A.js} +1 -1
- package/dist/{chunk-3G7YABRA.js → chunk-W7OPEMGJ.js} +4 -1
- package/dist/{chunk-XWIRU6UT.js → chunk-WBUG7XRL.js} +2 -2
- package/dist/{chunk-ZM2FNWIQ.js → chunk-WSOZ3FQN.js} +1 -1
- package/dist/chunk-X4IJS7LV.js +319 -0
- package/dist/{chunk-JIH32RH2.js → chunk-XA7Q2VQA.js} +1 -1
- package/dist/{chunk-GWP2VBFH.js → chunk-XLAXYPTK.js} +3 -3
- package/dist/client/index.js +4 -16
- package/dist/fleet/index.js +6 -6
- package/dist/forms/index.js +9 -325
- package/dist/forms/server.js +2 -2
- package/dist/images/index.js +4 -4
- package/dist/index.js +1 -1
- package/dist/layout/client.js +9 -9
- package/dist/layout/index.js +10 -10
- package/dist/llms/index.js +8 -8
- package/dist/maps/index.js +4 -4
- package/dist/mcp/sonor.d.ts +42 -3
- package/dist/mcp/sonor.js +25 -20
- package/dist/mcp/transport.d.ts +1 -1
- package/dist/press-kit/articles/Article.d.ts +89 -0
- package/dist/press-kit/articles/ArticleFAQ.d.ts +41 -0
- package/dist/press-kit/articles/ArticleFaqSection.d.ts +2 -0
- package/dist/press-kit/articles/ArticleList.d.ts +79 -0
- package/dist/press-kit/articles/ArticleViewTracker.d.ts +15 -0
- package/dist/press-kit/articles/AuthorCard.d.ts +10 -0
- package/dist/press-kit/articles/AuthorPage.d.ts +8 -0
- package/dist/press-kit/articles/ClusterLandingPage.d.ts +40 -0
- package/dist/press-kit/articles/ClusterNavigation.d.ts +37 -0
- package/dist/press-kit/articles/ManagedNewsletterForm.d.ts +12 -0
- package/dist/press-kit/articles/NewsletterShell.d.ts +17 -0
- package/dist/press-kit/articles/NewsletterWidget.d.ts +30 -0
- package/dist/press-kit/articles/PublicationLayout.d.ts +67 -0
- package/dist/press-kit/articles/PublicationSidebar.d.ts +36 -0
- package/dist/press-kit/articles/RelatedPosts.d.ts +22 -0
- package/dist/press-kit/articles/ServiceCallout.d.ts +56 -0
- package/dist/press-kit/articles/TableOfContents.d.ts +6 -0
- package/dist/press-kit/articles/article-photos.d.ts +9 -0
- package/dist/press-kit/articles/article-styles.d.ts +21 -0
- package/dist/press-kit/articles/article-tables.d.ts +12 -0
- package/dist/press-kit/articles/artwork.d.ts +13 -0
- package/dist/press-kit/articles/author-schema.d.ts +72 -0
- package/dist/press-kit/articles/author-social.d.ts +14 -0
- package/dist/press-kit/articles/excerpt.d.ts +17 -0
- package/dist/press-kit/articles/index.d.ts +79 -0
- package/dist/press-kit/articles/news-sitemap.d.ts +46 -0
- package/dist/press-kit/articles/processArticleHtml.d.ts +34 -0
- package/dist/press-kit/articles/public-reads.d.ts +26 -0
- package/dist/press-kit/articles/reading-time.d.ts +9 -0
- package/dist/press-kit/articles/routes.d.ts +52 -0
- package/dist/press-kit/articles/server-core.d.ts +461 -0
- package/dist/press-kit/articles/server-ui.d.ts +31 -0
- package/dist/press-kit/articles/types.d.ts +316 -0
- package/dist/press-kit/articles/widget-styles.d.ts +8 -0
- package/dist/reputation/index.js +3 -3
- package/dist/reputation/server.js +2 -2
- package/dist/revalidate/index.js +2 -2
- package/dist/runtime/index.js +5 -4
- package/dist/seo/client.js +6 -6
- package/dist/seo/index.js +7 -7
- package/dist/seo/llms.js +8 -8
- package/dist/seo/register-sitemap-cli.js +1 -1
- package/dist/seo/sitemap.js +6 -6
- package/dist/server/index.js +3 -2
- package/dist/shared/build-entries.d.ts +2 -1
- package/dist/shared/clientApiConfig.d.ts +2 -0
- package/dist/shared/import-specifiers.d.ts +1 -1
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.js +8 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +2 -2
- package/dist/sitemap/index.js +6 -6
- package/dist/sync/index.js +6 -6
- package/dist/website/images.js +4 -4
- package/dist/website/index.js +7 -7
- package/dist/website/popups.js +6 -6
- package/dist/{writeLLMsTxt-DGKLYXIW.js → writeLLMsTxt-VKHCM5IS.js} +5 -5
- package/docs/MIGRATING-TO-PRESS-KIT.md +83 -0
- package/docs.json +145 -29
- package/package.json +15 -5
- package/src/articles/README.md +5 -360
- package/src/mcp/README.md +16 -0
- package/src/og/README.md +1 -1
- package/src/runtime/README.md +4 -0
- package/dist/SiteChat-JSHPGAE3.js +0 -6
- package/dist/SiteDesignReporter-L2JBAKKK.js +0 -12
- package/dist/SitemapSync-VV2YSMIW.js +0 -9
- package/dist/article-tables-AXSZOGNW.js +0 -2
|
@@ -1,64 +1,12 @@
|
|
|
1
|
-
import { insertArticlePhotos } from './chunk-
|
|
2
|
-
import { generateArticleAuthorNode, resolveArticleArtwork, withArticleAuthorIdentity } from './chunk-
|
|
3
|
-
import { resolveArticleUrl, createPublicationRoutes, resolvePublicationUrl, articleCategorySlug } from './chunk-
|
|
1
|
+
import { insertArticlePhotos } from './chunk-M5SF7NCC.js';
|
|
2
|
+
import { generateArticleAuthorNode, resolveArticleArtwork, withArticleAuthorIdentity } from './chunk-SNRE3ZVZ.js';
|
|
3
|
+
import { resolveArticleUrl, createPublicationRoutes, resolvePublicationUrl, articleCategorySlug } from './chunk-4K735O3J.js';
|
|
4
4
|
import { withoutSchemaPlaceholders } from './chunk-VWWITFWM.js';
|
|
5
5
|
import { withSiteParam, withSiteBody } from './chunk-MJP63SSS.js';
|
|
6
6
|
import { resolveServerApiConfig } from './chunk-C7TLGL3R.js';
|
|
7
7
|
import { notFound } from 'next/navigation';
|
|
8
8
|
|
|
9
|
-
// src/articles/
|
|
10
|
-
async function fetchArticleBySlug({ apiUrl, apiKey, site }, slug) {
|
|
11
|
-
try {
|
|
12
|
-
const response = await fetch(withSiteParam(`${apiUrl}/public/articles/posts/${slug}`, site), {
|
|
13
|
-
headers: { "x-api-key": apiKey },
|
|
14
|
-
next: { revalidate: 60 }
|
|
15
|
-
});
|
|
16
|
-
if (!response.ok) {
|
|
17
|
-
if (response.status !== 404) console.error("[Articles] Failed to fetch post:", response.statusText);
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
const data = await response.json();
|
|
21
|
-
return data.post || null;
|
|
22
|
-
} catch (error) {
|
|
23
|
-
console.error("[Articles] Error fetching post:", error);
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
async function fetchArticleCategories({ apiUrl, apiKey, site }) {
|
|
28
|
-
try {
|
|
29
|
-
const response = await fetch(withSiteParam(`${apiUrl}/public/articles/categories`, site), {
|
|
30
|
-
headers: { "x-api-key": apiKey },
|
|
31
|
-
next: { revalidate: 300 }
|
|
32
|
-
});
|
|
33
|
-
if (!response.ok) return [];
|
|
34
|
-
const data = await response.json();
|
|
35
|
-
return data.categories || [];
|
|
36
|
-
} catch (error) {
|
|
37
|
-
console.error("[Articles] Error fetching categories:", error);
|
|
38
|
-
return [];
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
async function fetchRelatedArticles({ apiUrl, apiKey, site }, currentPostId, limit, cache = {}) {
|
|
42
|
-
try {
|
|
43
|
-
const response = await fetch(`${apiUrl}/public/articles/related`, {
|
|
44
|
-
method: "POST",
|
|
45
|
-
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
46
|
-
body: JSON.stringify(withSiteBody({ current_post_id: currentPostId, limit }, site)),
|
|
47
|
-
...cache.revalidate !== void 0 ? { next: { revalidate: cache.revalidate } } : {}
|
|
48
|
-
});
|
|
49
|
-
if (!response.ok) {
|
|
50
|
-
console.error("[Articles] Failed to fetch related posts:", response.statusText);
|
|
51
|
-
return [];
|
|
52
|
-
}
|
|
53
|
-
const data = await response.json();
|
|
54
|
-
return data.posts || [];
|
|
55
|
-
} catch (error) {
|
|
56
|
-
console.error("[Articles] Error fetching related posts:", error);
|
|
57
|
-
return [];
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// src/articles/excerpt.ts
|
|
9
|
+
// packages/press-kit/src/articles/excerpt.ts
|
|
62
10
|
function sanitizeExcerpt(raw, maxLength = 160) {
|
|
63
11
|
if (!raw) return "";
|
|
64
12
|
let text = String(raw).trim();
|
|
@@ -90,7 +38,7 @@ function sanitizeExcerpt(raw, maxLength = 160) {
|
|
|
90
38
|
return `${(lastSpace > maxLength * 0.6 ? cut.slice(0, lastSpace) : cut).replace(/[\s,;:—–-]+$/, "")}\u2026`;
|
|
91
39
|
}
|
|
92
40
|
|
|
93
|
-
// src/articles/news-sitemap.ts
|
|
41
|
+
// packages/press-kit/src/articles/news-sitemap.ts
|
|
94
42
|
var NEWS_SITEMAP_WINDOW_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
95
43
|
var NEWS_SITEMAP_MAX_URLS = 1e3;
|
|
96
44
|
var FEED_DEFAULT_ITEMS = 20;
|
|
@@ -128,7 +76,59 @@ function buildNewsSitemapXml(posts, options, now = /* @__PURE__ */ new Date()) {
|
|
|
128
76
|
${items.join("\n")}${items.length ? "\n" : ""}</urlset>`;
|
|
129
77
|
}
|
|
130
78
|
|
|
131
|
-
// src/articles/
|
|
79
|
+
// packages/press-kit/src/articles/public-reads.ts
|
|
80
|
+
async function fetchArticleBySlug({ apiUrl, apiKey, site }, slug) {
|
|
81
|
+
try {
|
|
82
|
+
const response = await fetch(withSiteParam(`${apiUrl}/public/articles/posts/${slug}`, site), {
|
|
83
|
+
headers: { "x-api-key": apiKey },
|
|
84
|
+
next: { revalidate: 60 }
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
if (response.status !== 404) console.error("[Articles] Failed to fetch post:", response.statusText);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const data = await response.json();
|
|
91
|
+
return data.post || null;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error("[Articles] Error fetching post:", error);
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function fetchArticleCategories({ apiUrl, apiKey, site }) {
|
|
98
|
+
try {
|
|
99
|
+
const response = await fetch(withSiteParam(`${apiUrl}/public/articles/categories`, site), {
|
|
100
|
+
headers: { "x-api-key": apiKey },
|
|
101
|
+
next: { revalidate: 300 }
|
|
102
|
+
});
|
|
103
|
+
if (!response.ok) return [];
|
|
104
|
+
const data = await response.json();
|
|
105
|
+
return data.categories || [];
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error("[Articles] Error fetching categories:", error);
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function fetchRelatedArticles({ apiUrl, apiKey, site }, currentPostId, limit, cache = {}) {
|
|
112
|
+
try {
|
|
113
|
+
const response = await fetch(`${apiUrl}/public/articles/related`, {
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: { "Content-Type": "application/json", "x-api-key": apiKey },
|
|
116
|
+
body: JSON.stringify(withSiteBody({ current_post_id: currentPostId, limit }, site)),
|
|
117
|
+
...cache.revalidate !== void 0 ? { next: { revalidate: cache.revalidate } } : {}
|
|
118
|
+
});
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
console.error("[Articles] Failed to fetch related posts:", response.statusText);
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
const data = await response.json();
|
|
124
|
+
return data.posts || [];
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error("[Articles] Error fetching related posts:", error);
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// packages/press-kit/src/articles/server-core.ts
|
|
132
132
|
var SEO_LIMITS = {
|
|
133
133
|
title: { min: 30, max: 60, recommended: 55 },
|
|
134
134
|
metaDescription: { min: 120, max: 160, recommended: 155 },
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { sanitizeFleetVersion, buildFleetHeartbeatPayload } from './chunk-ZTZQPYP6.js';
|
|
3
3
|
import { useDeferredActivation } from './chunk-YC7ELZS3.js';
|
|
4
|
-
import { resolveAnalyticsTarget } from './chunk-
|
|
5
|
-
import { sonorFetch } from './chunk-
|
|
6
|
-
import { SITE_KIT_VERSION } from './chunk-
|
|
4
|
+
import { resolveAnalyticsTarget } from './chunk-JO76F5WP.js';
|
|
5
|
+
import { sonorFetch } from './chunk-OIWFXUVD.js';
|
|
6
|
+
import { SITE_KIT_VERSION } from './chunk-C2UROFGZ.js';
|
|
7
7
|
import { useRef, useEffect } from 'react';
|
|
8
8
|
|
|
9
9
|
// src/fleet/heartbeat.ts
|
|
@@ -83,7 +83,7 @@ function resolveArticlePhotoPlacements(html, photos = []) {
|
|
|
83
83
|
return { headings: headings.map(({ start: _start, end: _end, ...heading }) => heading), placements };
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
// src/articles/article-photos.ts
|
|
86
|
+
// packages/press-kit/src/articles/article-photos.ts
|
|
87
87
|
var escape = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
88
88
|
function photoUrl(value) {
|
|
89
89
|
if (typeof value !== "string" || value.length > 2e3 || /[\s\\]/.test(value)) return null;
|
|
@@ -6,8 +6,8 @@ import { normalizeFormConfig, DEFAULT_FORM_SUCCESS_MESSAGE } from './chunk-5SQK3
|
|
|
6
6
|
import { DEFAULT_HONEYPOT_FIELD } from './chunk-NJCTQH2P.js';
|
|
7
7
|
import { onPageLeave } from './chunk-L2V5PUFN.js';
|
|
8
8
|
import { uuid } from './chunk-GJWI74ZZ.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { sonorFetch, sonorBeacon } from './chunk-OIWFXUVD.js';
|
|
10
|
+
import { readPublishedApiConfig, getClientApiConfig } from './chunk-W7OPEMGJ.js';
|
|
11
11
|
import { useRef, useCallback, useEffect, useState, useMemo } from 'react';
|
|
12
12
|
|
|
13
13
|
// src/forms/field-interactions.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isTokenMode, getFreshCredential, isSiteToken, refreshSiteToken, currentCredential, credentialBreakerId } from './chunk-
|
|
2
|
-
import { SITE_KIT_VERSION } from './chunk-
|
|
1
|
+
import { isTokenMode, getFreshCredential, isSiteToken, refreshSiteToken, currentCredential, credentialBreakerId } from './chunk-C4AFNZT2.js';
|
|
2
|
+
import { SITE_KIT_VERSION } from './chunk-C2UROFGZ.js';
|
|
3
3
|
|
|
4
4
|
// src/shared/fetchWithRetry.ts
|
|
5
5
|
function backoffDelay(attempt, response) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { getSiteDesignTokens, tokensForReport, shouldReportDesign, sendSiteDesign } from './chunk-
|
|
2
|
+
import { getSiteDesignTokens, tokensForReport, shouldReportDesign, sendSiteDesign } from './chunk-TT4JZDKM.js';
|
|
3
3
|
import { designTokensHash } from './chunk-IHG36STL.js';
|
|
4
4
|
import { useDeferredActivation } from './chunk-YC7ELZS3.js';
|
|
5
|
-
import { resolveAnalyticsTarget } from './chunk-
|
|
5
|
+
import { resolveAnalyticsTarget } from './chunk-JO76F5WP.js';
|
|
6
6
|
import { useRef, useEffect } from 'react';
|
|
7
7
|
|
|
8
8
|
var STAMP_KEY = (site) => `_sk_design_sent:${site}`;
|
|
@@ -54,7 +54,7 @@ function useSignal() {
|
|
|
54
54
|
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
55
55
|
}
|
|
56
56
|
var LazySignalCore = dynamic(
|
|
57
|
-
() => import('./SignalCore-
|
|
57
|
+
() => import('./SignalCore-5KABGX5C.js').then((m) => ({ default: m.SignalCore })),
|
|
58
58
|
{ ssr: false }
|
|
59
59
|
);
|
|
60
60
|
function SignalBridge({
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { SITE_EDIT_PARAM } from './chunk-6G43IRWR.js';
|
|
3
|
-
import { publishSiteCredential } from './chunk-
|
|
4
|
-
import { FleetHeartbeat } from './chunk-
|
|
3
|
+
import { publishSiteCredential } from './chunk-U7Y3QG3A.js';
|
|
4
|
+
import { FleetHeartbeat } from './chunk-LPKKSYKX.js';
|
|
5
5
|
import { useDeferredActivation } from './chunk-YC7ELZS3.js';
|
|
6
6
|
import { resolveSiteHost } from './chunk-FESKKJAS.js';
|
|
7
7
|
import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-ZKADJNR2.js';
|
|
8
|
-
import { announceFrameReady, isCrossOriginFrame } from './chunk-
|
|
9
|
-
import { SignalBridge } from './chunk-
|
|
8
|
+
import { announceFrameReady, isCrossOriginFrame } from './chunk-JO76F5WP.js';
|
|
9
|
+
import { SignalBridge } from './chunk-QCZHYO5M.js';
|
|
10
10
|
import React, { useState, useRef, useCallback, useEffect, Suspense } from 'react';
|
|
11
11
|
import dynamic from 'next/dynamic';
|
|
12
12
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -33,23 +33,23 @@ function startEditBridge() {
|
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
var LazyAnalyticsProvider = dynamic(
|
|
36
|
-
() => import('./AnalyticsProvider-
|
|
36
|
+
() => import('./AnalyticsProvider-QXO33JUF.js').then((m) => ({ default: m.AnalyticsProvider })),
|
|
37
37
|
{ ssr: false }
|
|
38
38
|
);
|
|
39
39
|
var LazySiteChat = dynamic(
|
|
40
|
-
() => import('./SiteChat-
|
|
40
|
+
() => import('./SiteChat-JQ46ZIJ4.js').then((m) => ({ default: m.SiteChat })),
|
|
41
41
|
{ ssr: false }
|
|
42
42
|
);
|
|
43
43
|
var LazySitePopups = dynamic(
|
|
44
|
-
() => import('./SitePopups-
|
|
44
|
+
() => import('./SitePopups-WZBKX5Q3.js').then((m) => ({ default: m.SitePopups })),
|
|
45
45
|
{ ssr: false }
|
|
46
46
|
);
|
|
47
47
|
var LazySiteDesignReporter = dynamic(
|
|
48
|
-
() => import('./SiteDesignReporter-
|
|
48
|
+
() => import('./SiteDesignReporter-N7L6DR4J.js').then((m) => ({ default: m.SiteDesignReporter })),
|
|
49
49
|
{ ssr: false }
|
|
50
50
|
);
|
|
51
51
|
var LazySitemapSync = dynamic(
|
|
52
|
-
() => import('./SitemapSync-
|
|
52
|
+
() => import('./SitemapSync-GY6UADRI.js').then((m) => ({ default: m.SitemapSync })),
|
|
53
53
|
{ ssr: false }
|
|
54
54
|
);
|
|
55
55
|
function SiteKitClientProviders({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { locToPath, isMalformedSitemapPath, inferPageType } from './chunk-YVKRYQRG.js';
|
|
3
|
-
import { resolveAnalyticsTarget } from './chunk-
|
|
4
|
-
import { sonorFetch } from './chunk-
|
|
3
|
+
import { resolveAnalyticsTarget } from './chunk-JO76F5WP.js';
|
|
4
|
+
import { sonorFetch } from './chunk-OIWFXUVD.js';
|
|
5
5
|
import { useRef, useEffect } from 'react';
|
|
6
6
|
|
|
7
7
|
var SYNC_STAMP_KEY = "_sk_sitemap_synced_at";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { resolvePublicationUrl, createPublicationRoutes } from './chunk-
|
|
1
|
+
import { resolvePublicationUrl, createPublicationRoutes } from './chunk-4K735O3J.js';
|
|
2
2
|
|
|
3
|
-
// src/articles/artwork.ts
|
|
3
|
+
// packages/press-kit/src/articles/artwork.ts
|
|
4
4
|
function resolveArticleArtwork(post, placement = "card") {
|
|
5
5
|
const editorial = placement === "article" && !!post.editorial_image;
|
|
6
6
|
const src = (editorial ? post.editorial_image : post.featured_image) || void 0;
|
|
@@ -18,7 +18,7 @@ function articleArtworkImageStyle(artwork) {
|
|
|
18
18
|
return artwork.composed ? { display: "block", height: "auto", maxHeight: "none", objectFit: "contain", transform: "none" } : void 0;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
// src/articles/author-schema.ts
|
|
21
|
+
// packages/press-kit/src/articles/author-schema.ts
|
|
22
22
|
var ARTICLE_TYPES = /* @__PURE__ */ new Set(["Article", "BlogPosting", "NewsArticle", "TechArticle", "Report", "ScholarlyArticle"]);
|
|
23
23
|
function isAbsoluteUrl(value) {
|
|
24
24
|
return /^https?:\/\//i.test(value);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { toHexColor, normalizeDesignTokens, designTokensHash } from './chunk-IHG36STL.js';
|
|
2
2
|
import { contrastRatio, parseColor, relativeLuminance } from './chunk-S22FSH7C.js';
|
|
3
|
-
import { resolveAnalyticsTarget } from './chunk-
|
|
4
|
-
import { sonorFetch } from './chunk-
|
|
5
|
-
import { SITE_KIT_VERSION } from './chunk-
|
|
3
|
+
import { resolveAnalyticsTarget } from './chunk-JO76F5WP.js';
|
|
4
|
+
import { sonorFetch } from './chunk-OIWFXUVD.js';
|
|
5
|
+
import { SITE_KIT_VERSION } from './chunk-C2UROFGZ.js';
|
|
6
6
|
|
|
7
7
|
// src/website/design.ts
|
|
8
8
|
var SITE_DESIGN_PATH = "/api/public/site/design";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveSiteHost } from './chunk-FESKKJAS.js';
|
|
2
|
-
import { configureSiteCredential, currentCredential } from './chunk-
|
|
2
|
+
import { configureSiteCredential, currentCredential } from './chunk-C4AFNZT2.js';
|
|
3
3
|
|
|
4
4
|
// src/shared/publishCredential.ts
|
|
5
5
|
function publishSiteCredential({
|
|
@@ -21,5 +21,8 @@ function getClientApiConfig(options = {}) {
|
|
|
21
21
|
const published = readPublishedApiConfig();
|
|
22
22
|
return { apiUrl: published.apiUrl || DEFAULT_SONOR_API_URL, apiKey: published.apiKey };
|
|
23
23
|
}
|
|
24
|
+
function readPublishedSite() {
|
|
25
|
+
return siteKitWindow()?.__SITE_KIT_SITE__ || void 0;
|
|
26
|
+
}
|
|
24
27
|
|
|
25
|
-
export { DEFAULT_SONOR_API_URL, getClientApiConfig, readPublishedApiConfig };
|
|
28
|
+
export { DEFAULT_SONOR_API_URL, getClientApiConfig, readPublishedApiConfig, readPublishedSite };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { sonorFetch } from './chunk-OIWFXUVD.js';
|
|
2
|
+
import { getClientApiConfig } from './chunk-W7OPEMGJ.js';
|
|
3
3
|
|
|
4
4
|
// src/sync/api.ts
|
|
5
5
|
function getApiConfig() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { trackedFreshFetch } from './chunk-UAYAJPEP.js';
|
|
2
2
|
import { isNextControlFlow } from './chunk-C7TLGL3R.js';
|
|
3
3
|
import { monotonicMs } from './chunk-MH2DSGC6.js';
|
|
4
|
-
import { SITE_KIT_VERSION } from './chunk-
|
|
4
|
+
import { SITE_KIT_VERSION } from './chunk-C2UROFGZ.js';
|
|
5
5
|
import 'server-only';
|
|
6
6
|
|
|
7
7
|
var MINT_PATH = "/api/public/site-token";
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { sonorFetch } from './chunk-OIWFXUVD.js';
|
|
2
|
+
import { readPublishedApiConfig } from './chunk-W7OPEMGJ.js';
|
|
3
|
+
|
|
4
|
+
// src/forms/formsApi.ts
|
|
5
|
+
var config = null;
|
|
6
|
+
function configureFormsApi(options) {
|
|
7
|
+
config = options;
|
|
8
|
+
}
|
|
9
|
+
function getConfig() {
|
|
10
|
+
if (config) return config;
|
|
11
|
+
const { apiUrl, apiKey } = readPublishedApiConfig();
|
|
12
|
+
if (apiUrl && apiKey) {
|
|
13
|
+
return { baseUrl: apiUrl, apiKey };
|
|
14
|
+
}
|
|
15
|
+
throw new Error(
|
|
16
|
+
"Forms API not configured. Use SiteKitLayout in your root layout or call configureFormsApi() first."
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
async function apiRequest(method, path, body) {
|
|
20
|
+
const { baseUrl, apiKey, getAuthToken } = getConfig();
|
|
21
|
+
const headers = {
|
|
22
|
+
"Content-Type": "application/json"
|
|
23
|
+
};
|
|
24
|
+
if (apiKey) {
|
|
25
|
+
headers["x-api-key"] = apiKey;
|
|
26
|
+
} else if (getAuthToken) {
|
|
27
|
+
const token = await getAuthToken();
|
|
28
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
29
|
+
}
|
|
30
|
+
const response = await sonorFetch(`${baseUrl}${path}`, {
|
|
31
|
+
method,
|
|
32
|
+
headers,
|
|
33
|
+
body: body ? JSON.stringify(body) : void 0
|
|
34
|
+
}, { retries: 0 });
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
37
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
if (response.status === 204) {
|
|
40
|
+
return void 0;
|
|
41
|
+
}
|
|
42
|
+
return response.json();
|
|
43
|
+
}
|
|
44
|
+
var formsApi = {
|
|
45
|
+
/**
|
|
46
|
+
* List all forms for a project
|
|
47
|
+
*/
|
|
48
|
+
async list(options = {}) {
|
|
49
|
+
const params = new URLSearchParams();
|
|
50
|
+
if (options.projectId) params.set("projectId", options.projectId);
|
|
51
|
+
if (options.formType) params.set("formType", options.formType);
|
|
52
|
+
if (options.isActive !== void 0) params.set("isActive", String(options.isActive));
|
|
53
|
+
if (options.search) params.set("search", options.search);
|
|
54
|
+
const query = params.toString();
|
|
55
|
+
const result = await apiRequest("GET", `/forms${query ? `?${query}` : ""}`);
|
|
56
|
+
return result.data;
|
|
57
|
+
},
|
|
58
|
+
/**
|
|
59
|
+
* Get a single form by ID or slug
|
|
60
|
+
*/
|
|
61
|
+
async get(idOrSlug) {
|
|
62
|
+
return apiRequest("GET", `/forms/${idOrSlug}`);
|
|
63
|
+
},
|
|
64
|
+
/**
|
|
65
|
+
* Create a new form
|
|
66
|
+
*/
|
|
67
|
+
async create(input) {
|
|
68
|
+
return apiRequest("POST", "/forms", input);
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* Update an existing form
|
|
72
|
+
*/
|
|
73
|
+
async update(id, input) {
|
|
74
|
+
return apiRequest("PUT", `/forms/${id}`, input);
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* Delete a form
|
|
78
|
+
*/
|
|
79
|
+
async delete(id) {
|
|
80
|
+
return apiRequest("DELETE", `/forms/${id}`);
|
|
81
|
+
},
|
|
82
|
+
/**
|
|
83
|
+
* Add a field to an existing form
|
|
84
|
+
*/
|
|
85
|
+
async addField(formId, field2) {
|
|
86
|
+
const form = await formsApi.get(formId);
|
|
87
|
+
const maxSortOrder = Math.max(0, ...(form.fields || []).map((f) => f.sortOrder || 0));
|
|
88
|
+
return formsApi.update(formId, {
|
|
89
|
+
fields: [
|
|
90
|
+
...form.fields || [],
|
|
91
|
+
{ ...field2, sortOrder: field2.sortOrder ?? maxSortOrder + 1 }
|
|
92
|
+
]
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
/**
|
|
96
|
+
* Update a field in an existing form
|
|
97
|
+
*/
|
|
98
|
+
async updateField(formId, fieldSlug, updates) {
|
|
99
|
+
const form = await formsApi.get(formId);
|
|
100
|
+
return formsApi.update(formId, {
|
|
101
|
+
fields: (form.fields || []).map(
|
|
102
|
+
(f) => f.slug === fieldSlug ? { ...f, ...updates } : f
|
|
103
|
+
)
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
/**
|
|
107
|
+
* Remove a field from a form
|
|
108
|
+
*/
|
|
109
|
+
async removeField(formId, fieldSlug) {
|
|
110
|
+
const form = await formsApi.get(formId);
|
|
111
|
+
return formsApi.update(formId, {
|
|
112
|
+
fields: (form.fields || []).filter((f) => f.slug !== fieldSlug)
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
/**
|
|
116
|
+
* Reorder fields in a form
|
|
117
|
+
*/
|
|
118
|
+
async reorderFields(formId, fieldSlugs) {
|
|
119
|
+
const form = await formsApi.get(formId);
|
|
120
|
+
const fieldsMap = new Map((form.fields || []).map((f) => [f.slug, f]));
|
|
121
|
+
const orderedFields = fieldSlugs.map((slug, index) => {
|
|
122
|
+
const field2 = fieldsMap.get(slug);
|
|
123
|
+
if (!field2) throw new Error(`Field not found: ${slug}`);
|
|
124
|
+
return { ...field2, sortOrder: index };
|
|
125
|
+
});
|
|
126
|
+
return formsApi.update(formId, { fields: orderedFields });
|
|
127
|
+
},
|
|
128
|
+
/**
|
|
129
|
+
* Clone a form
|
|
130
|
+
*/
|
|
131
|
+
async clone(formId, newSlug, newName) {
|
|
132
|
+
const form = await formsApi.get(formId);
|
|
133
|
+
return formsApi.create({
|
|
134
|
+
projectId: form.projectId,
|
|
135
|
+
slug: newSlug,
|
|
136
|
+
name: newName || `${form.name} (Copy)`,
|
|
137
|
+
description: form.description,
|
|
138
|
+
formType: form.formType,
|
|
139
|
+
successMessage: form.successMessage,
|
|
140
|
+
redirectUrl: form.redirectUrl,
|
|
141
|
+
notificationEmails: form.notificationEmails,
|
|
142
|
+
submitButtonText: form.submitButtonText,
|
|
143
|
+
layout: form.layout,
|
|
144
|
+
showProgress: form.showProgress,
|
|
145
|
+
enableSaveDraft: form.enableSaveDraft,
|
|
146
|
+
isActive: false,
|
|
147
|
+
// Clone as inactive
|
|
148
|
+
fields: (form.fields || []).map(({ id, ...field2 }) => field2),
|
|
149
|
+
// Remove IDs
|
|
150
|
+
steps: (form.steps || []).map(({ id, ...step }) => step)
|
|
151
|
+
// Remove IDs
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
/**
|
|
155
|
+
* Activate or deactivate a form
|
|
156
|
+
*/
|
|
157
|
+
async setActive(formId, isActive) {
|
|
158
|
+
return formsApi.update(formId, { isActive });
|
|
159
|
+
},
|
|
160
|
+
/**
|
|
161
|
+
* Sync a form definition to the backend
|
|
162
|
+
* Creates the form if it doesn't exist, updates if it does
|
|
163
|
+
* Perfect for defining forms in code during development
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```tsx
|
|
167
|
+
* // In your app initialization or form component
|
|
168
|
+
* await formsApi.sync({
|
|
169
|
+
* slug: 'contact',
|
|
170
|
+
* name: 'Contact Form',
|
|
171
|
+
* formType: 'prospect',
|
|
172
|
+
* fields: [
|
|
173
|
+
* field.text('name', 'Your Name', { isRequired: true }),
|
|
174
|
+
* field.email('email', 'Email Address'),
|
|
175
|
+
* field.phone('phone', 'Phone Number'),
|
|
176
|
+
* field.textarea('message', 'Message'),
|
|
177
|
+
* ]
|
|
178
|
+
* })
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
async sync(input) {
|
|
182
|
+
return apiRequest(
|
|
183
|
+
"POST",
|
|
184
|
+
"/api/public/forms/sync",
|
|
185
|
+
input
|
|
186
|
+
);
|
|
187
|
+
},
|
|
188
|
+
/**
|
|
189
|
+
* Sync multiple forms at once
|
|
190
|
+
* Useful for initializing all forms in your app
|
|
191
|
+
*
|
|
192
|
+
* Runs sequentially to avoid bursting the API (many hosts throttle concurrent POSTs → 429).
|
|
193
|
+
*/
|
|
194
|
+
async syncAll(forms) {
|
|
195
|
+
const results = [];
|
|
196
|
+
for (const form of forms) {
|
|
197
|
+
results.push(await formsApi.sync(form));
|
|
198
|
+
}
|
|
199
|
+
return results;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
var field = {
|
|
203
|
+
text: (slug, label, options) => ({
|
|
204
|
+
slug,
|
|
205
|
+
label,
|
|
206
|
+
fieldType: "text",
|
|
207
|
+
...options
|
|
208
|
+
}),
|
|
209
|
+
email: (slug, label, options) => ({
|
|
210
|
+
slug,
|
|
211
|
+
label,
|
|
212
|
+
fieldType: "email",
|
|
213
|
+
isRequired: true,
|
|
214
|
+
...options
|
|
215
|
+
}),
|
|
216
|
+
phone: (slug, label, options) => ({
|
|
217
|
+
slug,
|
|
218
|
+
label,
|
|
219
|
+
fieldType: "phone",
|
|
220
|
+
...options
|
|
221
|
+
}),
|
|
222
|
+
textarea: (slug, label, options) => ({
|
|
223
|
+
slug,
|
|
224
|
+
label,
|
|
225
|
+
fieldType: "textarea",
|
|
226
|
+
...options
|
|
227
|
+
}),
|
|
228
|
+
select: (slug, label, choices, options) => ({
|
|
229
|
+
slug,
|
|
230
|
+
label,
|
|
231
|
+
fieldType: "select",
|
|
232
|
+
options: choices,
|
|
233
|
+
...options
|
|
234
|
+
}),
|
|
235
|
+
radio: (slug, label, choices, options) => ({
|
|
236
|
+
slug,
|
|
237
|
+
label,
|
|
238
|
+
fieldType: "radio",
|
|
239
|
+
options: choices,
|
|
240
|
+
...options
|
|
241
|
+
}),
|
|
242
|
+
checkbox: (slug, label, options) => ({
|
|
243
|
+
slug,
|
|
244
|
+
label,
|
|
245
|
+
fieldType: "checkbox",
|
|
246
|
+
...options
|
|
247
|
+
}),
|
|
248
|
+
date: (slug, label, options) => ({
|
|
249
|
+
slug,
|
|
250
|
+
label,
|
|
251
|
+
fieldType: "date",
|
|
252
|
+
...options
|
|
253
|
+
}),
|
|
254
|
+
number: (slug, label, options) => ({
|
|
255
|
+
slug,
|
|
256
|
+
label,
|
|
257
|
+
fieldType: "number",
|
|
258
|
+
...options
|
|
259
|
+
}),
|
|
260
|
+
rating: (slug, label, options) => ({
|
|
261
|
+
slug,
|
|
262
|
+
label,
|
|
263
|
+
fieldType: "rating",
|
|
264
|
+
...options
|
|
265
|
+
}),
|
|
266
|
+
file: (slug, label, options) => ({
|
|
267
|
+
slug,
|
|
268
|
+
label,
|
|
269
|
+
fieldType: "file",
|
|
270
|
+
...options
|
|
271
|
+
}),
|
|
272
|
+
hidden: (slug, defaultValue) => ({
|
|
273
|
+
slug,
|
|
274
|
+
label: "",
|
|
275
|
+
fieldType: "hidden",
|
|
276
|
+
defaultValue
|
|
277
|
+
}),
|
|
278
|
+
heading: (slug, label) => ({
|
|
279
|
+
slug,
|
|
280
|
+
label,
|
|
281
|
+
fieldType: "heading"
|
|
282
|
+
}),
|
|
283
|
+
paragraph: (slug, label) => ({
|
|
284
|
+
slug,
|
|
285
|
+
label,
|
|
286
|
+
fieldType: "paragraph"
|
|
287
|
+
})
|
|
288
|
+
};
|
|
289
|
+
function defineForm(definition) {
|
|
290
|
+
const fieldsWithOrder = definition.fields.map((f, index) => ({
|
|
291
|
+
...f,
|
|
292
|
+
sortOrder: f.sortOrder ?? index
|
|
293
|
+
}));
|
|
294
|
+
return {
|
|
295
|
+
...definition,
|
|
296
|
+
fields: fieldsWithOrder,
|
|
297
|
+
formType: definition.formType || "contact",
|
|
298
|
+
successMessage: definition.successMessage || "Thank you for your submission!",
|
|
299
|
+
submitButtonText: definition.submitButtonText || "Submit",
|
|
300
|
+
layout: definition.layout || "stacked",
|
|
301
|
+
isActive: definition.isActive ?? true
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
async function initializeForms(forms) {
|
|
305
|
+
if (typeof window === "undefined") {
|
|
306
|
+
console.log(`[Site-Kit] ${forms.length} form(s) ready to sync: ${forms.map((f) => f.slug).join(", ")}`);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
try {
|
|
310
|
+
const results = await formsApi.syncAll(forms);
|
|
311
|
+
const created = results.filter((r) => r.created).length;
|
|
312
|
+
const updated = results.filter((r) => r.updated).length;
|
|
313
|
+
console.log(`[Site-Kit] Forms synced: ${created} created, ${updated} updated`);
|
|
314
|
+
} catch (error) {
|
|
315
|
+
console.error("[Site-Kit] Failed to sync forms:", error);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export { configureFormsApi, defineForm, field, formsApi, initializeForms };
|