@sonordev/site-kit 8.5.2 → 8.7.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 +16 -0
- package/agent-manifest.json +1 -1
- package/dist/{AnalyticsProvider-HSJMHYBA.js → AnalyticsProvider-3UIQMIRW.js} +6 -6
- package/dist/{ArticleViewTracker-XEA6ZY67.js → ArticleViewTracker-KNXP2DXL.js} +5 -5
- package/dist/{BlocksPopup-DUTOENMQ.js → BlocksPopup-DFE32GPX.js} +9 -8
- package/dist/{ChatWidget-PMVQTSEU.js → ChatWidget-L74L4YAD.js} +6 -6
- package/dist/FileField-P3PLEAON.js +237 -0
- package/dist/{FormSpotlight-RTPJPLQ3.js → FormSpotlight-DNBSBRIE.js} +2 -2
- package/dist/{FormStage-UANGD66Z.js → FormStage-I4JGLT57.js} +2 -2
- package/dist/{ManagedForm-4AACRHEY.js → ManagedForm-GJRGBM6W.js} +8 -8
- package/dist/{ManagedNewsletterForm-RWKFWZ72.js → ManagedNewsletterForm-AUZ6YB7G.js} +11 -11
- package/dist/{SignalCore-XULLPKPX.js → SignalCore-UV7K7PT4.js} +5 -5
- package/dist/SiteChat-6UWE545R.js +6 -0
- package/dist/SiteDesignReporter-ZSU76DZJ.js +13 -0
- package/dist/{SitePopups-US6VQN7X.js → SitePopups-XHWU7GNF.js} +6 -6
- package/dist/SitemapSync-ELWV6W7Y.js +9 -0
- package/dist/_client/booking-widget.js +5 -5
- package/dist/affiliates/index.js +3 -3
- package/dist/analytics/content-text.d.ts +17 -0
- package/dist/analytics/index.js +6 -6
- package/dist/{article-styles-VASFBYA3.js → article-styles-D7VCDXMG.js} +2 -1
- package/dist/article-tables-W45BE353.js +3 -0
- package/dist/articles/index.js +7 -20
- package/dist/articles/server-ui.js +29 -55
- package/dist/articles/server.js +6 -5
- package/dist/chat/index.js +9 -9
- package/dist/{chunk-3RDJKIYO.js → chunk-2WDWQI7K.js} +1 -1
- package/dist/{chunk-DLTLXYOV.js → chunk-36ZMNBXZ.js} +4 -9
- package/dist/chunk-3MJNBOUO.js +8 -0
- package/dist/{chunk-IXA7ZB6U.js → chunk-3MLWIBHX.js} +1 -1
- package/dist/{chunk-BF7TZYC3.js → chunk-52KO4LKD.js} +1 -1
- package/dist/{chunk-ZDUTXHM6.js → chunk-5WHBYQJ4.js} +3 -3
- package/dist/{chunk-5D7ZISUP.js → chunk-7DYMM6SS.js} +11 -6
- package/dist/{chunk-HNYECNCU.js → chunk-7YB3QA4P.js} +15 -7
- package/dist/{chunk-N4ZCNYWF.js → chunk-A2MDVP47.js} +1 -1
- package/dist/{chunk-E4PTMORJ.js → chunk-AL5UCWLI.js} +23 -8
- package/dist/{chunk-ANVHRT35.js → chunk-BAJUXQTH.js} +2 -2
- package/dist/{chunk-ITQND6IB.js → chunk-BJYX6SFI.js} +2 -2
- package/dist/{chunk-TYAVHRWH.js → chunk-CVADNHJ4.js} +8 -2
- package/dist/{chunk-5BRHTBPO.js → chunk-DJIGFX33.js} +1 -1
- package/dist/{chunk-ZSU7KTIE.js → chunk-DPYGC7WE.js} +2 -2
- package/dist/{chunk-XA7Q2VQA.js → chunk-EK7P62DT.js} +1 -1
- package/dist/chunk-FXR5PJDL.js +420 -0
- package/dist/{chunk-GLLFIE2R.js → chunk-G5FD7UXK.js} +2 -2
- package/dist/{chunk-OFQ3BU52.js → chunk-HM7CDWFK.js} +1 -1
- package/dist/{chunk-Q4Y3WIHE.js → chunk-HWQPCZOX.js} +1 -1
- package/dist/{chunk-6KU7STM3.js → chunk-HY7ZEU2C.js} +3 -1
- package/dist/chunk-IBHBEUZV.js +27 -0
- package/dist/{chunk-7HRYSLY2.js → chunk-IXZBOOAD.js} +4 -4
- package/dist/chunk-JESLPEST.js +14 -0
- package/dist/{chunk-BC7JMY4Z.js → chunk-JG53YJLM.js} +58 -1
- package/dist/{chunk-FVXCQC7W.js → chunk-JWCCY72G.js} +1 -1
- package/dist/{chunk-RI2N2EBI.js → chunk-JYITKUUB.js} +13 -5
- package/dist/chunk-KIYACQW3.js +1 -0
- package/dist/{chunk-YW3LNSBM.js → chunk-KLIDCNML.js} +1 -1
- package/dist/{chunk-3PT6SO65.js → chunk-L2KSHJS2.js} +5 -5
- package/dist/{chunk-27LYZVPP.js → chunk-LGWN6KCN.js} +2 -2
- package/dist/{chunk-GTVOB5RN.js → chunk-MJW6YIDJ.js} +1 -1
- package/dist/{chunk-CFSIGEUW.js → chunk-MNORERMF.js} +1 -1
- package/dist/{chunk-Y35BWW2C.js → chunk-ODOV76VW.js} +1 -1
- package/dist/{chunk-EQHGPB3J.js → chunk-OHLCE4GC.js} +2 -2
- package/dist/{chunk-OEA7U4HJ.js → chunk-P5PRR2BB.js} +1 -1
- package/dist/{chunk-JJ4JS3LD.js → chunk-PAYCK7FC.js} +1 -1
- package/dist/{chunk-DLM4FFNH.js → chunk-QTBAKOCZ.js} +1 -1
- package/dist/{chunk-2QFIYYMP.js → chunk-RHT7OZNF.js} +1 -1
- package/dist/{chunk-UGZ3B5AK.js → chunk-RWWSOYJO.js} +9 -9
- package/dist/{chunk-T6U6J3QK.js → chunk-T6TWPKBL.js} +1 -1
- package/dist/{chunk-5SQK3D53.js → chunk-TYSIAWC3.js} +1 -0
- package/dist/{chunk-24NM64IV.js → chunk-U4OQJQK6.js} +3 -3
- package/dist/{chunk-GDQKDL3E.js → chunk-UYOE3HA4.js} +2 -2
- package/dist/chunk-VEJD5EJ2.js +344 -0
- package/dist/{chunk-LNSF6BJC.js → chunk-VPZJ7ZTL.js} +2 -2
- package/dist/chunk-XAZC2TUD.js +1119 -0
- package/dist/{chunk-A7RZQI6H.js → chunk-XC2TWYDV.js} +3 -3
- package/dist/{chunk-URJN75ZG.js → chunk-XIDWNXZN.js} +3 -3
- package/dist/chunk-XLAHRN4B.js +1 -0
- package/dist/{chunk-URZTBPZO.js → chunk-XZFOQ2V4.js} +113 -93
- package/dist/{chunk-I4LMZNBN.js → chunk-YYPYLYZM.js} +1 -1
- package/dist/client/index.js +4 -4
- package/dist/contracts/broadcast-layouts.d.ts +133 -0
- package/dist/contracts/business-claims.d.ts +456 -0
- package/dist/contracts/campaign-normalize.d.ts +2 -0
- package/dist/contracts/entries.d.ts +1 -1
- package/dist/contracts/funnels.d.ts +576 -0
- package/dist/contracts/inbox.d.ts +42 -0
- package/dist/contracts/llms.d.ts +200 -0
- package/dist/contracts/outreach.d.ts +267 -0
- package/dist/contracts/page-titles.d.ts +140 -0
- package/dist/contracts/portfolio.d.ts +170 -0
- package/dist/contracts/public-url-host.d.ts +10 -0
- package/dist/contracts/publication-branding.d.ts +151 -0
- package/dist/contracts/publication-charter.d.ts +14 -0
- package/dist/contracts/site-cache.d.ts +2 -0
- package/dist/fleet/index.js +6 -6
- package/dist/forms/FileField.d.ts +3 -1
- package/dist/forms/PrivateFileField.d.ts +3 -0
- package/dist/forms/index.js +11 -11
- package/dist/forms/private-file-rules.d.ts +8 -0
- package/dist/forms/server.js +5 -5
- package/dist/forms/static.js +3 -3
- package/dist/forms/styles.css +17 -1
- package/dist/forms/types.d.ts +4 -0
- package/dist/images/index.js +4 -4
- package/dist/index.js +1 -1
- package/dist/landing/contract.d.ts +2 -13
- package/dist/landing/contract.js +2 -0
- package/dist/landing/index.js +4 -2
- package/dist/landing/managed-server.d.ts +21 -0
- package/dist/landing/managed.d.ts +11 -0
- package/dist/landing/metadata.js +2 -0
- package/dist/landing/server.d.ts +5 -0
- package/dist/landing/server.js +19 -2
- package/dist/layout/client.js +9 -9
- package/dist/layout/index.js +10 -10
- package/dist/llms/contract.js +2 -1
- package/dist/llms/index.js +9 -7
- package/dist/llms/merge.d.ts +29 -0
- package/dist/maps/index.js +3 -3
- package/dist/mcp/sonor.js +12 -11
- package/dist/portfolio/contract.js +1 -1
- package/dist/press-kit/articles/article-body.d.ts +13 -0
- package/dist/press-kit/articles/article-heading-ids.d.ts +7 -0
- package/dist/press-kit/articles/article-headings.d.ts +61 -0
- package/dist/press-kit/articles/html-tags.d.ts +46 -0
- package/dist/press-kit/articles/types.d.ts +2 -0
- package/dist/revalidate/index.js +3 -3
- package/dist/runtime/index.js +3 -3
- package/dist/seo/client.js +6 -6
- package/dist/seo/index.js +14 -13
- package/dist/seo/llms/contract.js +2 -1
- package/dist/seo/llms.js +9 -7
- package/dist/seo/meta/contract.js +2 -1
- package/dist/seo/register-sitemap-cli.js +1 -1
- package/dist/seo/server.js +5 -4
- package/dist/seo/sitemap.js +7 -5
- package/dist/seo-meta/contract.js +2 -1
- package/dist/server/index.js +3 -3
- package/dist/{server-api-EGOKC7Q3.js → server-api-XIKDWSNO.js} +2 -2
- package/dist/shared/build-entries.d.ts +3 -1
- package/dist/shared/markdown.d.ts +7 -6
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +2 -2
- package/dist/sitemap/index.js +7 -5
- package/dist/slots/index.js +2 -2
- package/dist/sync/index.js +5 -5
- package/dist/website/contract.js +2 -1
- package/dist/website/images.js +4 -4
- package/dist/website/index.js +10 -9
- package/dist/website/landing/server.js +19 -2
- package/dist/website/landing.js +4 -2
- package/dist/website/popups.js +9 -8
- package/dist/website/slots.js +2 -2
- package/dist/{writeLLMsTxt-BAK5XMRR.js → writeLLMsTxt-QN2HIVT4.js} +6 -4
- package/docs.json +5 -0
- package/package.json +1 -1
- package/src/analytics/README.md +1 -1
- package/src/forms/README.md +22 -0
- package/src/landing/README.md +64 -0
- package/src/llms/README.md +52 -20
- package/dist/FileField-F7BG4XAZ.js +0 -83
- package/dist/SiteChat-P4CRBRJZ.js +0 -6
- package/dist/SiteDesignReporter-QDVP4WMK.js +0 -12
- package/dist/SitemapSync-5FBRDGHG.js +0 -9
- package/dist/article-tables-6XHVULPU.js +0 -2
- package/dist/chunk-EKBEOXTH.js +0 -114
- package/dist/chunk-NZ4RXN3G.js +0 -145
- package/dist/chunk-OSYCOC3K.js +0 -21
- /package/dist/{chunk-7ZWO5HDQ.js → chunk-BTHEQDN4.js} +0 -0
- /package/dist/{chunk-BQR4IPBW.js → chunk-ISRBSTB7.js} +0 -0
- /package/dist/{chunk-IHG36STL.js → chunk-XHYE24HU.js} +0 -0
|
@@ -26,6 +26,176 @@ export interface FrameReadyMessage {
|
|
|
26
26
|
export declare function isFrameReadyMessage(data: unknown): data is FrameReadyMessage;
|
|
27
27
|
/** Bump on breaking changes to the collapse policy. */
|
|
28
28
|
export declare const PORTFOLIO_CONTRACT_VERSION: 1;
|
|
29
|
+
/** The four beats, in reading order. */
|
|
30
|
+
export declare const CASE_STUDY_STAGES: readonly ['problem', 'build', 'proof', 'outcome'];
|
|
31
|
+
export type CaseStudyStage = (typeof CASE_STUDY_STAGES)[number];
|
|
32
|
+
/** The generic name of each beat and the question its sections answer. */
|
|
33
|
+
export declare const CASE_STUDY_STAGE_COPY: Record<CaseStudyStage, {
|
|
34
|
+
name: string;
|
|
35
|
+
question: string;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* A site's own names for the four stages ("Heat", "Shape", "Temper",
|
|
39
|
+
* "Finish"), set per project in the dashboard (branding is per project) and
|
|
40
|
+
* read everywhere a stage is named: the editor, the public portfolio config,
|
|
41
|
+
* the site itself. A stage left unnamed falls back to its generic name. The
|
|
42
|
+
* ids never change; only what people see does.
|
|
43
|
+
*/
|
|
44
|
+
export type CaseStudyStageNames = Partial<Record<CaseStudyStage, string>>;
|
|
45
|
+
/** The longest a stage name may run. It's a heading word, a rail label, a tab. */
|
|
46
|
+
export declare const STAGE_NAME_MAX_CHARS = 24;
|
|
47
|
+
/**
|
|
48
|
+
* What's wrong with a set of stage names, or an empty list. Absent passes
|
|
49
|
+
* (generic names); present must be an object of short text keyed by stage.
|
|
50
|
+
*/
|
|
51
|
+
export declare function stageNamesProblems(names: unknown): string[];
|
|
52
|
+
/** The name a stage is shown under: the site's own when set, else the generic one. */
|
|
53
|
+
export declare function stageName(names: CaseStudyStageNames | null | undefined, stage: CaseStudyStage): string;
|
|
54
|
+
/**
|
|
55
|
+
* Every section type a case study can hold, in canonical reading order:
|
|
56
|
+
* hero, then each stage's sections, then the two that aren't rendered as
|
|
57
|
+
* sections of the story (SEO metadata, the closing CTA). This is THE list;
|
|
58
|
+
* the Sonor API and agency-site-kit import it rather than keeping their own.
|
|
59
|
+
*/
|
|
60
|
+
export declare const PORTFOLIO_SECTION_TYPES: readonly ['portfolioHero', 'portfolioChallenges', 'portfolioBeforeAfter', 'portfolioStrategy', 'portfolioSiteArchitecture', 'portfolioDesignSystem', 'portfolioFeatureSpotlight', 'portfolioGallery', 'portfolioVideo', 'portfolioTechStack', 'portfolioPerformance', 'portfolioSpeedComparison', 'portfolioResults', 'portfolioMetricsTimeline', 'portfolioConversionFunnel', 'portfolioServices', 'portfolioTeam', 'portfolioTestimonial', 'portfolioDetails', 'portfolioSeo', 'portfolioCTA'];
|
|
61
|
+
export type PortfolioSectionType = (typeof PORTFOLIO_SECTION_TYPES)[number];
|
|
62
|
+
export declare function isPortfolioSectionType(value: unknown): value is PortfolioSectionType;
|
|
63
|
+
/**
|
|
64
|
+
* Which stage each section belongs to. Null for the hero (it opens the page,
|
|
65
|
+
* above the story), SEO metadata (never rendered as a section) and the CTA
|
|
66
|
+
* (closes the page, after the story). Typed over every section type so a new
|
|
67
|
+
* type without a stage is a compile error, not a section that renders last.
|
|
68
|
+
*/
|
|
69
|
+
export declare const SECTION_STAGE: Record<PortfolioSectionType, CaseStudyStage | null>;
|
|
70
|
+
/** The stage a section type belongs to, or null when it sits outside the story. Unknown types are null. */
|
|
71
|
+
export declare function sectionStage(type: string): CaseStudyStage | null;
|
|
72
|
+
/**
|
|
73
|
+
* The one section each stage can't do without. A stage with other sections
|
|
74
|
+
* but not this one is told so by {@link caseStudyStageStatus}: a proof stage
|
|
75
|
+
* that's only a speed comparison has no measurement of the finished build.
|
|
76
|
+
*/
|
|
77
|
+
export declare const STAGE_CORE_SECTION: Record<CaseStudyStage, PortfolioSectionType>;
|
|
78
|
+
/**
|
|
79
|
+
* Canonical display order, derived from the list above so it can't disagree
|
|
80
|
+
* with the stages. Renderers sort by this when nobody has reordered; the
|
|
81
|
+
* dashboard's stored order only ever moves a section within its stage.
|
|
82
|
+
*/
|
|
83
|
+
export declare const PORTFOLIO_SECTION_ORDER: Record<PortfolioSectionType, number>;
|
|
84
|
+
/** The least a section needs for the ordering helpers: its type. Anything else rides along. */
|
|
85
|
+
export interface SectionLike {
|
|
86
|
+
sectionType: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The sections in the order the case study reads.
|
|
90
|
+
*
|
|
91
|
+
* The arc always wins: the hero, then problem, build, proof, outcome, then
|
|
92
|
+
* the CTA. Within a stage, the agency's own order is kept once it has
|
|
93
|
+
* reordered in the dashboard (`sectionsOrdered`); otherwise the canonical
|
|
94
|
+
* order. Before this, a reordered case study rendered in exactly its stored
|
|
95
|
+
* order, so Results could sit above Challenges and the page read backwards.
|
|
96
|
+
* Never mutates.
|
|
97
|
+
*/
|
|
98
|
+
export declare function orderSections<T extends SectionLike>(sections: readonly T[] | null | undefined, options?: {
|
|
99
|
+
sectionsOrdered?: boolean;
|
|
100
|
+
}): T[];
|
|
101
|
+
/** One beat of the story with the sections that tell it. */
|
|
102
|
+
export interface CaseStudyStageGroup<T extends SectionLike = SectionLike> {
|
|
103
|
+
stage: CaseStudyStage;
|
|
104
|
+
/** 1-based position among the stages this case study actually has. */
|
|
105
|
+
index: number;
|
|
106
|
+
sections: T[];
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The story's beats, in order, each with its sections in reading order
|
|
110
|
+
* ({@link orderSections}). A stage with no sections is left out and the
|
|
111
|
+
* numbering follows, so a software case study with nothing measured runs
|
|
112
|
+
* problem, build, outcome as 1, 2, 3. The hero, SEO and CTA aren't in any
|
|
113
|
+
* group; a renderer places them itself.
|
|
114
|
+
*/
|
|
115
|
+
export declare function groupSectionsByStage<T extends SectionLike>(sections: readonly T[] | null | undefined, options?: {
|
|
116
|
+
sectionsOrdered?: boolean;
|
|
117
|
+
}): CaseStudyStageGroup<T>[];
|
|
118
|
+
/** What each stage of a case study has and what it's missing. */
|
|
119
|
+
export interface CaseStudyStageStatus {
|
|
120
|
+
stage: CaseStudyStage;
|
|
121
|
+
/** The section types present, in reading order. */
|
|
122
|
+
present: PortfolioSectionType[];
|
|
123
|
+
/** True when the stage's core section ({@link STAGE_CORE_SECTION}) is present. */
|
|
124
|
+
complete: boolean;
|
|
125
|
+
/** Null when complete; otherwise one sentence on what the stage is missing. */
|
|
126
|
+
missing: string | null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Each stage's status, all four, in order, whether or not the case study has
|
|
130
|
+
* sections in it. The dashboard shows these beside the editor so an empty
|
|
131
|
+
* proof stage is seen before the case study is published, not after.
|
|
132
|
+
*/
|
|
133
|
+
export declare function caseStudyStageStatus(sections: readonly SectionLike[] | null | undefined): CaseStudyStageStatus[];
|
|
134
|
+
export interface CaseStudyNarrative {
|
|
135
|
+
/** One sentence: what this project was, in the end. */
|
|
136
|
+
thesis: string;
|
|
137
|
+
/** One or two sentences opening each stage, specific to this project. A stage may be left unwritten. */
|
|
138
|
+
stages: Partial<Record<CaseStudyStage, string>>;
|
|
139
|
+
}
|
|
140
|
+
/** The longest a thesis or a stage lede may run. Longer is a paragraph, and the sections are the paragraphs. */
|
|
141
|
+
export declare const NARRATIVE_MAX_CHARS = 320;
|
|
142
|
+
/**
|
|
143
|
+
* What's wrong with a narrative, or an empty list when nothing is. An absent
|
|
144
|
+
* narrative is legacy data and passes (renderers fall back to house copy);
|
|
145
|
+
* one that's present must be prose, under the length, with no unknown stage.
|
|
146
|
+
*/
|
|
147
|
+
export declare function narrativeProblems(narrative: unknown): string[];
|
|
148
|
+
/** Agent-native contract: JSON Schema for {@link CaseStudyNarrative}. */
|
|
149
|
+
export declare const CASE_STUDY_NARRATIVE_JSON_SCHEMA: {
|
|
150
|
+
readonly $schema: 'http://json-schema.org/draft-07/schema#';
|
|
151
|
+
readonly $id: 'https://sonor.io/schemas/case-study-narrative.v1.json';
|
|
152
|
+
readonly title: 'CaseStudyNarrative';
|
|
153
|
+
readonly description: 'The thesis of a case study and the lede that opens each of its four stages.';
|
|
154
|
+
readonly type: 'object';
|
|
155
|
+
readonly required: readonly ['thesis'];
|
|
156
|
+
readonly properties: {
|
|
157
|
+
readonly thesis: {
|
|
158
|
+
readonly type: 'string';
|
|
159
|
+
readonly minLength: 1;
|
|
160
|
+
readonly maxLength: 320;
|
|
161
|
+
};
|
|
162
|
+
readonly stages: {
|
|
163
|
+
readonly type: 'object';
|
|
164
|
+
readonly properties: {
|
|
165
|
+
[k: string]: {
|
|
166
|
+
type: string;
|
|
167
|
+
maxLength: number;
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
readonly additionalProperties: false;
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
readonly additionalProperties: false;
|
|
174
|
+
};
|
|
175
|
+
export interface ChallengeLike {
|
|
176
|
+
id?: string | null;
|
|
177
|
+
title?: string;
|
|
178
|
+
}
|
|
179
|
+
export interface PhaseLike {
|
|
180
|
+
resolves?: readonly string[] | null;
|
|
181
|
+
}
|
|
182
|
+
export interface ResultLike {
|
|
183
|
+
proves?: readonly string[] | null;
|
|
184
|
+
}
|
|
185
|
+
/** A stable id for the n-th challenge (1-based): "c1", "c2"… Writers that don't mint their own use this. */
|
|
186
|
+
export declare function challengeId(position: number): string;
|
|
187
|
+
/**
|
|
188
|
+
* The problems with how a case study's story hangs together, each one
|
|
189
|
+
* sentence, or an empty list. Read by the generator's audit and the
|
|
190
|
+
* dashboard. It judges links only where they've been written: a case study
|
|
191
|
+
* whose challenges carry no ids has nothing to check and passes, so legacy
|
|
192
|
+
* content isn't failed for predating the thread.
|
|
193
|
+
*/
|
|
194
|
+
export declare function caseStudyFlowProblems(input: {
|
|
195
|
+
challenges?: readonly ChallengeLike[] | null;
|
|
196
|
+
phases?: readonly PhaseLike[] | null;
|
|
197
|
+
results?: readonly ResultLike[] | null;
|
|
198
|
+
}): string[];
|
|
29
199
|
/** Minimal KPI shape the policy reads — callers pass their own richer tiles. */
|
|
30
200
|
export interface KpiLike {
|
|
31
201
|
label: string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shared literal-host SSRF policy. Pass URL.hostname (which canonicalizes
|
|
3
|
+
* numeric IPv4 spellings), or an address returned by a DNS lookup. IPv6 may
|
|
4
|
+
* have the brackets URL.hostname retains. This isn't a URL validator and
|
|
5
|
+
* doesn't trim input, resolve DNS, follow redirects or open a connection.
|
|
6
|
+
* Callers still enforce their protocol/port rules and check or pin the DNS
|
|
7
|
+
* addresses used by each connection; a false result alone can't prove a
|
|
8
|
+
* destination is public.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isBlockedPublicUrlHost(rawHost: string): boolean;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { type BroadcastStyleId, type PublicationCardLayout } from './broadcast-layouts';
|
|
2
|
+
import { type PublicationCharter } from './publication-charter';
|
|
3
|
+
export { PUBLICATION_CHARTER_FIELDS, parsePublicationCharter, parseSiteCharters, publicationCharterContext, publicationCharterFor, type PublicationCharter, } from './publication-charter';
|
|
4
|
+
/** The stored profile's version. A breaking change to the shape bumps it. */
|
|
5
|
+
export declare const PUBLICATION_BRANDING_VERSION: 1;
|
|
6
|
+
/** Where a publication appears. `social` overrides every social network; each network can override again. */
|
|
7
|
+
export declare const PUBLICATION_PLATFORMS: readonly ['publication', 'email', 'social', 'instagram', 'facebook', 'linkedin', 'gbp'];
|
|
8
|
+
export type PublicationPlatform = (typeof PUBLICATION_PLATFORMS)[number];
|
|
9
|
+
/** The sections of a profile and of each platform override, in the order they're read. */
|
|
10
|
+
export declare const PUBLICATION_BRANDING_SECTIONS: readonly ['identity', 'colors', 'typography', 'editorial', 'newsletter'];
|
|
11
|
+
export type PublicationBrandingSection = (typeof PUBLICATION_BRANDING_SECTIONS)[number];
|
|
12
|
+
export declare const PUBLICATION_IDENTITY_FIELDS: readonly ['publicationName', 'wordmark', 'tagline', 'publisherName', 'publisherUrl', 'publisherLogoUrl', 'logos', 'squareLogoUrl', 'fullLogoUrl'];
|
|
13
|
+
export declare const PUBLICATION_LOGO_VARIANTS: readonly ['default', 'light', 'dark'];
|
|
14
|
+
export declare const PUBLICATION_COLOR_FIELDS: readonly ['primary', 'secondary', 'accent', 'background', 'surface', 'text', 'muted', 'border'];
|
|
15
|
+
export declare const PUBLICATION_TYPOGRAPHY_FIELDS: readonly ['heading', 'body', 'mono', 'emailHeadingFallback', 'emailBodyFallback'];
|
|
16
|
+
export declare const PUBLICATION_EDITORIAL_FIELDS: readonly ['articleStyle', 'cardLayout', 'focusClosingBackground', 'charter', 'siteCharters'];
|
|
17
|
+
export declare const FOCUS_CLOSING_BACKGROUNDS: readonly ['planned_photo', 'article_atmosphere'];
|
|
18
|
+
export declare const PUBLICATION_NEWSLETTER_FIELDS: readonly ['name', 'tagline', 'layout', 'maxWidth'];
|
|
19
|
+
/** Fonts every email client has, the only families an email fallback may name. Lowercase. */
|
|
20
|
+
export declare const EMAIL_SAFE_FONTS: ReadonlySet<string>;
|
|
21
|
+
/** CSS generic families: written bare and lowercase in a font stack, never quoted. */
|
|
22
|
+
export declare const GENERIC_FONT_FAMILIES: ReadonlySet<string>;
|
|
23
|
+
export interface PublicationIdentity {
|
|
24
|
+
publicationName?: string;
|
|
25
|
+
wordmark?: string;
|
|
26
|
+
tagline?: string;
|
|
27
|
+
publisherName?: string;
|
|
28
|
+
publisherUrl?: string;
|
|
29
|
+
/** The publisher's attribution mark, separate from the publication masthead. */
|
|
30
|
+
publisherLogoUrl?: string;
|
|
31
|
+
/** The publication's square mark; independent of theme variants and publisher attribution. */
|
|
32
|
+
squareLogoUrl?: string;
|
|
33
|
+
/** The publication's full/display logo; wordmark remains a text fallback. */
|
|
34
|
+
fullLogoUrl?: string;
|
|
35
|
+
/** Legacy theme variants, not square/full logo roles. */
|
|
36
|
+
logos?: {
|
|
37
|
+
default?: string;
|
|
38
|
+
light?: string;
|
|
39
|
+
dark?: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface PublicationColors {
|
|
43
|
+
primary?: string;
|
|
44
|
+
secondary?: string;
|
|
45
|
+
accent?: string;
|
|
46
|
+
background?: string;
|
|
47
|
+
surface?: string;
|
|
48
|
+
text?: string;
|
|
49
|
+
muted?: string;
|
|
50
|
+
border?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface PublicationTypography {
|
|
53
|
+
heading?: string;
|
|
54
|
+
body?: string;
|
|
55
|
+
mono?: string;
|
|
56
|
+
emailHeadingFallback?: string;
|
|
57
|
+
emailBodyFallback?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface PublicationEditorial {
|
|
60
|
+
charter?: PublicationCharter;
|
|
61
|
+
siteCharters?: Record<string, PublicationCharter>;
|
|
62
|
+
/** Shared Broadcast style for articles, reviews and generated posts; portfolio is excluded. Legacy wire name. */
|
|
63
|
+
articleStyle?: BroadcastStyleId;
|
|
64
|
+
cardLayout?: PublicationCardLayout;
|
|
65
|
+
/** Focus closing frames may reuse the article's saved atmosphere and real author portrait. */
|
|
66
|
+
focusClosingBackground?: (typeof FOCUS_CLOSING_BACKGROUNDS)[number];
|
|
67
|
+
}
|
|
68
|
+
export interface PublicationNewsletter {
|
|
69
|
+
name?: string;
|
|
70
|
+
tagline?: string;
|
|
71
|
+
layout?: 'editorial';
|
|
72
|
+
maxWidth?: 600 | 640;
|
|
73
|
+
}
|
|
74
|
+
export interface PublicationBrandingSections {
|
|
75
|
+
identity?: PublicationIdentity;
|
|
76
|
+
colors?: PublicationColors;
|
|
77
|
+
typography?: PublicationTypography;
|
|
78
|
+
editorial?: PublicationEditorial;
|
|
79
|
+
newsletter?: PublicationNewsletter;
|
|
80
|
+
}
|
|
81
|
+
/** Exactly the object stored in projects.settings.publication_branding. */
|
|
82
|
+
export interface PublicationBranding extends PublicationBrandingSections {
|
|
83
|
+
version: typeof PUBLICATION_BRANDING_VERSION;
|
|
84
|
+
platforms?: Partial<Record<PublicationPlatform, PublicationBrandingSections>>;
|
|
85
|
+
}
|
|
86
|
+
export type PublicationBrandingProfile = PublicationBranding;
|
|
87
|
+
type LeafPatch<T> = {
|
|
88
|
+
[K in keyof T]?: NonNullable<T[K]> extends object ? LeafPatch<NonNullable<T[K]>> : T[K] | null;
|
|
89
|
+
};
|
|
90
|
+
export type PublicationBrandingSectionsPatch = LeafPatch<PublicationBrandingSections>;
|
|
91
|
+
/** A change: any leaf set to a value, or to null to clear that override. */
|
|
92
|
+
export interface PublicationBrandingPatch extends PublicationBrandingSectionsPatch {
|
|
93
|
+
version?: typeof PUBLICATION_BRANDING_VERSION;
|
|
94
|
+
platforms?: Partial<Record<PublicationPlatform, PublicationBrandingSectionsPatch>>;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A refusal, naming the field: `publication_branding.colors.primary: use a
|
|
98
|
+
* valid opaque color`. One case throws a plain Error instead: a charter set on
|
|
99
|
+
* a channel override, which belongs to the publication or a site.
|
|
100
|
+
*/
|
|
101
|
+
export declare class PublicationBrandingValidationError extends Error {
|
|
102
|
+
readonly path: string;
|
|
103
|
+
constructor(path: string, reason: string);
|
|
104
|
+
}
|
|
105
|
+
/** True for a control character (U+0000-U+001F, U+007F) anywhere in the text. */
|
|
106
|
+
export declare function containsControlCharacters(value: string): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* A CSS font stack as data, never a stylesheet fragment: quoted family names
|
|
109
|
+
* and lowercase generic families joined by commas ("'Brand Display',serif"),
|
|
110
|
+
* or undefined when the value carries rules, variables, url() or anything
|
|
111
|
+
* that isn't a family name. The theme aliases heading, body and mono drop out.
|
|
112
|
+
*/
|
|
113
|
+
export declare function safeFontStack(value: unknown): string | undefined;
|
|
114
|
+
export interface PublicationBrandingValidatorOptions {
|
|
115
|
+
/**
|
|
116
|
+
* True when a URL's hostname must never be stored as a logo or publisher
|
|
117
|
+
* URL: loopback, private and link-local ranges, `localhost` and the like.
|
|
118
|
+
* Each API passes the shared `public-url-host` policy. It receives
|
|
119
|
+
* `new URL(value).hostname`, so IPv6 keeps its brackets.
|
|
120
|
+
*/
|
|
121
|
+
isBlockedHost: (hostname: string) => boolean;
|
|
122
|
+
}
|
|
123
|
+
export interface PublicationBrandingValidator {
|
|
124
|
+
/** A whole saved profile. Retired card layouts still read. */
|
|
125
|
+
validatePublicationBranding(value: unknown): PublicationBranding;
|
|
126
|
+
/** A change. Leaves may be null (clear that override); a card layout must be one drawn today. */
|
|
127
|
+
validatePublicationBrandingPatch(value: unknown): PublicationBrandingPatch;
|
|
128
|
+
/** The sections of a profile or a platform override, at `path`. */
|
|
129
|
+
validatePublicationBrandingSections(input: unknown, path: string, patch: boolean): PublicationBrandingSections | PublicationBrandingSectionsPatch;
|
|
130
|
+
/**
|
|
131
|
+
* The saved profile with the change applied: a null leaf clears just that
|
|
132
|
+
* override and empty containers are pruned. No profile yet reads as
|
|
133
|
+
* `{ version: 1 }`; a change that sets nothing returns the profile as it was.
|
|
134
|
+
*/
|
|
135
|
+
mergePublicationBrandingPatch(current: unknown, patch: unknown): PublicationBranding;
|
|
136
|
+
/** One text leaf: trimmed, 1 to max characters (0 when empty is allowed), no control characters. */
|
|
137
|
+
text(value: unknown, path: string, max: number, empty?: boolean): string;
|
|
138
|
+
/** One URL leaf: a public HTTPS URL without credentials, normalized. */
|
|
139
|
+
url(value: unknown, path: string): string;
|
|
140
|
+
/** One font leaf, normalized by safeFontStack; email fallbacks may name only EMAIL_SAFE_FONTS. */
|
|
141
|
+
font(value: unknown, path: string, emailSafe?: boolean): string;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Leaf-wise merge of a validated change into a profile layer: a null leaf
|
|
145
|
+
* deletes that key, an object merges recursively, and a container left empty
|
|
146
|
+
* is removed. The inputs are never mutated. The Sonor API layers resolved
|
|
147
|
+
* branding with the same merge.
|
|
148
|
+
*/
|
|
149
|
+
export declare function mergePublicationBrandingLayers(current: Record<string, unknown>, patch: Record<string, unknown>): Record<string, unknown>;
|
|
150
|
+
/** Single source of truth for publication-branding validation, bound to the caller's host guard. */
|
|
151
|
+
export declare function createPublicationBrandingValidator(options: PublicationBrandingValidatorOptions): PublicationBrandingValidator;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A publication's editorial charter: data-only direction (who it's for, what
|
|
3
|
+
* they're deciding, the proof it holds itself to), never evidence of
|
|
4
|
+
* expertise or permission to publish private material. Part of
|
|
5
|
+
* `@sonordev/contracts/publication-branding`, which re-exports it; Signal's
|
|
6
|
+
* writers read it into their prompts and the Sonor API stores it in a
|
|
7
|
+
* publication's branding. Pure: no I/O, no Node built-ins.
|
|
8
|
+
*/
|
|
9
|
+
export declare const PUBLICATION_CHARTER_FIELDS: readonly ['audience', 'readerDecisions', 'perspective', 'expertise', 'proofStandards', 'tone', 'recurringSeries', 'nonAuthority'];
|
|
10
|
+
export type PublicationCharter = Partial<Record<typeof PUBLICATION_CHARTER_FIELDS[number], string>>;
|
|
11
|
+
export declare function parsePublicationCharter(value: unknown, patch?: boolean): PublicationCharter;
|
|
12
|
+
export declare function parseSiteCharters(value: unknown, patch?: boolean): Record<string, PublicationCharter>;
|
|
13
|
+
export declare function publicationCharterFor(editorial: unknown, site?: string | null): PublicationCharter;
|
|
14
|
+
export declare function publicationCharterContext(charter?: PublicationCharter): string;
|
|
@@ -29,6 +29,8 @@ export declare const SITE_CACHE_TAGS: {
|
|
|
29
29
|
readonly portfolio: 'portfolio';
|
|
30
30
|
/** Products, services, events and membership plans (commerce-kit). */
|
|
31
31
|
readonly commerce: 'commerce';
|
|
32
|
+
/** Published managed landing pages. Draft previews never enter this cache. */
|
|
33
|
+
readonly funnels: 'sonor-funnels';
|
|
32
34
|
};
|
|
33
35
|
export type SiteCacheTag = (typeof SITE_CACHE_TAGS)[keyof typeof SITE_CACHE_TAGS];
|
|
34
36
|
/** The body Sonor POSTs to the revalidation route. */
|
package/dist/fleet/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { FLEET_HEARTBEAT_PATH, FleetHeartbeat, detectNextVersion, sendFleetHeartbeat } from '../chunk-
|
|
2
|
+
export { FLEET_HEARTBEAT_PATH, FleetHeartbeat, detectNextVersion, sendFleetHeartbeat } from '../chunk-5WHBYQJ4.js';
|
|
3
3
|
export { FLEET_CONTRACT_VERSION, FLEET_MODULES, FLEET_MODULES_MAX, FLEET_SITE_MAX_LENGTH, FLEET_VERSION_MAX_LENGTH, FLEET_VERSION_PATTERN, buildFleetHeartbeatPayload, isFleetModule, normalizeFleetModules, normalizeFleetSite, sanitizeFleetVersion } from '../chunk-ZTZQPYP6.js';
|
|
4
4
|
import '../chunk-YC7ELZS3.js';
|
|
5
|
-
import '../chunk-
|
|
6
|
-
import '../chunk-
|
|
7
|
-
import '../chunk-
|
|
8
|
-
import '../chunk-
|
|
5
|
+
import '../chunk-QTBAKOCZ.js';
|
|
6
|
+
import '../chunk-VEJD5EJ2.js';
|
|
7
|
+
import '../chunk-UYOE3HA4.js';
|
|
8
|
+
import '../chunk-P5PRR2BB.js';
|
|
9
9
|
import '../chunk-W7OPEMGJ.js';
|
|
10
|
-
import '../chunk-
|
|
10
|
+
import '../chunk-MNORERMF.js';
|
|
11
11
|
import '../chunk-PKBMQBKP.js';
|
|
@@ -24,5 +24,7 @@ export interface FileFieldProps {
|
|
|
24
24
|
classPrefix: string;
|
|
25
25
|
baseInputStyle: React.CSSProperties;
|
|
26
26
|
onChange: (value: unknown) => void;
|
|
27
|
+
ariaInvalid?: boolean;
|
|
28
|
+
describedBy?: string;
|
|
27
29
|
}
|
|
28
|
-
export declare function FileField({ field, inputId, classPrefix, baseInputStyle, onChange, }: FileFieldProps): React.JSX.Element;
|
|
30
|
+
export declare function FileField({ field, inputId, classPrefix, baseInputStyle, onChange, ariaInvalid, describedBy, }: FileFieldProps): React.JSX.Element;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FileFieldProps } from './FileField';
|
|
3
|
+
export declare function PrivateFileField({ field, inputId, onChange, ariaInvalid, describedBy }: Pick<FileFieldProps, 'field' | 'inputId' | 'onChange' | 'ariaInvalid' | 'describedBy'>): React.JSX.Element;
|
package/dist/forms/index.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { configureFormsApi, defineForm, field, formsApi, initializeForms } from '../chunk-
|
|
3
|
-
export { FormClient, ManagedForm } from '../chunk-3PT6SO65.js';
|
|
4
|
-
import '../chunk-DLTLXYOV.js';
|
|
5
|
-
export { DatePicker } from '../chunk-SOD2F6C2.js';
|
|
2
|
+
export { configureFormsApi, defineForm, field, formsApi, initializeForms } from '../chunk-RHT7OZNF.js';
|
|
6
3
|
export { FormCelebration } from '../chunk-YGGDU6C3.js';
|
|
7
|
-
export {
|
|
4
|
+
export { FormClient, ManagedForm } from '../chunk-L2KSHJS2.js';
|
|
5
|
+
import '../chunk-36ZMNBXZ.js';
|
|
6
|
+
export { DatePicker } from '../chunk-SOD2F6C2.js';
|
|
7
|
+
export { useForm, useFormTracking } from '../chunk-LGWN6KCN.js';
|
|
8
8
|
import '../chunk-Q6E4OPGG.js';
|
|
9
9
|
import '../chunk-5ROTTMBL.js';
|
|
10
|
-
export { FormEnhancer } from '../chunk-
|
|
10
|
+
export { FormEnhancer } from '../chunk-G5FD7UXK.js';
|
|
11
11
|
import '../chunk-C2FZBUSS.js';
|
|
12
12
|
import '../chunk-YC7ELZS3.js';
|
|
13
13
|
import '../chunk-DXO6SBMD.js';
|
|
14
|
-
export { FormField as FormFieldComponent, autocompleteFor } from '../chunk-
|
|
15
|
-
export { DEFAULT_FORM_SUCCESS_MESSAGE } from '../chunk-
|
|
14
|
+
export { FormField as FormFieldComponent, autocompleteFor } from '../chunk-CVADNHJ4.js';
|
|
15
|
+
export { DEFAULT_FORM_SUCCESS_MESSAGE } from '../chunk-TYSIAWC3.js';
|
|
16
16
|
import '../chunk-HW7B43E5.js';
|
|
17
17
|
import '../chunk-NJCTQH2P.js';
|
|
18
18
|
import '../chunk-L2V5PUFN.js';
|
|
19
19
|
import '../chunk-GJWI74ZZ.js';
|
|
20
20
|
import '../chunk-5TM3WPCI.js';
|
|
21
|
-
import '../chunk-
|
|
22
|
-
import '../chunk-
|
|
21
|
+
import '../chunk-UYOE3HA4.js';
|
|
22
|
+
import '../chunk-P5PRR2BB.js';
|
|
23
23
|
import '../chunk-W7OPEMGJ.js';
|
|
24
|
-
import '../chunk-
|
|
24
|
+
import '../chunk-MNORERMF.js';
|
|
25
25
|
import '../chunk-PKBMQBKP.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const PRIVATE_FILE_MAX_BYTES: number;
|
|
2
|
+
export declare const PRIVATE_FILE_TYPES: readonly ['application/pdf', 'image/jpeg', 'image/png', 'image/webp'];
|
|
3
|
+
export declare const PRIVATE_FILE_ACCEPT = ".pdf,.jpg,.jpeg,.png,.webp";
|
|
4
|
+
export declare function validatePrivateFileSelection(files: Array<{
|
|
5
|
+
name: string;
|
|
6
|
+
size: number;
|
|
7
|
+
type: string;
|
|
8
|
+
}>, maxFiles?: number): string | null;
|
package/dist/forms/server.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export { ServerForm, getFormConfig } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { ServerForm, getFormConfig } from '../chunk-DPYGC7WE.js';
|
|
2
|
+
import '../chunk-G5FD7UXK.js';
|
|
3
3
|
import '../chunk-C2FZBUSS.js';
|
|
4
4
|
import '../chunk-YC7ELZS3.js';
|
|
5
|
-
export { StaticForm } from '../chunk-
|
|
5
|
+
export { StaticForm } from '../chunk-VPZJ7ZTL.js';
|
|
6
6
|
import '../chunk-DXO6SBMD.js';
|
|
7
|
-
import '../chunk-
|
|
8
|
-
import '../chunk-
|
|
7
|
+
import '../chunk-CVADNHJ4.js';
|
|
8
|
+
import '../chunk-TYSIAWC3.js';
|
|
9
9
|
import '../chunk-HW7B43E5.js';
|
|
10
10
|
import '../chunk-NJCTQH2P.js';
|
|
11
11
|
import '../chunk-C7TLGL3R.js';
|
package/dist/forms/static.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { StaticForm } from '../chunk-
|
|
1
|
+
export { StaticForm } from '../chunk-VPZJ7ZTL.js';
|
|
2
2
|
import '../chunk-DXO6SBMD.js';
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-CVADNHJ4.js';
|
|
4
|
+
import '../chunk-TYSIAWC3.js';
|
|
5
5
|
import '../chunk-HW7B43E5.js';
|
|
6
6
|
import '../chunk-NJCTQH2P.js';
|
|
7
7
|
import '../chunk-PKBMQBKP.js';
|
package/dist/forms/styles.css
CHANGED
|
@@ -439,4 +439,20 @@
|
|
|
439
439
|
color: var(--sk-text-tertiary);
|
|
440
440
|
margin: 8px 0;
|
|
441
441
|
}
|
|
442
|
-
|
|
442
|
+
.sk-file-dropzone { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; min-height: 180px; padding: 24px 16px; border: 1.5px dashed rgba(var(--sk-primary-rgb), .38); border-radius: 12px; background: rgba(var(--sk-primary-rgb), .035); color: var(--sk-primary); text-align: center; cursor: pointer; }
|
|
443
|
+
.sk-file-dropzone--active, .sk-file-dropzone:focus-within { outline: 2px solid var(--sk-primary); outline-offset: 3px; background: rgba(var(--sk-primary-rgb), .075); }
|
|
444
|
+
.sk-file-dropzone--busy { cursor: progress; }
|
|
445
|
+
.sk-file-dropzone__title { display: block; font-size: 15px; font-weight: 600; }
|
|
446
|
+
.sk-file-dropzone__hint { font-size: 12px; color: var(--sk-text-secondary); }
|
|
447
|
+
.sk-file-dropzone__hint span { color: var(--sk-primary); text-decoration: underline; text-underline-offset: 3px; }
|
|
448
|
+
.sk-file-dropzone__formats { font-size: 10px; color: var(--sk-text-tertiary); margin-top: 4px; }
|
|
449
|
+
.sk-file-dropzone__input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
|
|
450
|
+
.sk-private-files__list { list-style: none; padding: 0; margin: 12px 0 0; }
|
|
451
|
+
.sk-private-files__list li { display: flex; align-items: center; gap: 12px; justify-content: space-between; border: 1px solid rgba(var(--sk-primary-rgb), .15); border-radius: 9px; padding: 12px; margin-top: 8px; }
|
|
452
|
+
.sk-private-files__name { min-width: 0; overflow-wrap: anywhere; font-size: 12px; color: var(--sk-text-primary); }
|
|
453
|
+
.sk-private-files__name small { display: block; font-size: 10px; color: var(--sk-text-tertiary); margin-top: 4px; }
|
|
454
|
+
.sk-private-files__list li > div { display: flex; gap: 10px; flex-shrink: 0; }
|
|
455
|
+
.sk-private-files__list button { padding: 5px 0; min-height: 32px; font-size: 10px; color: var(--sk-primary); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
|
|
456
|
+
.sk-private-files__list button:disabled { opacity: .5; cursor: wait; }
|
|
457
|
+
.sk-private-files__status { font-size: 10px; color: var(--sk-text-tertiary); margin: 9px 0 0; line-height: 1.7; }
|
|
458
|
+
.sk-private-files__error { font-size: 12px; color: var(--sk-error); margin: 9px 0 0; line-height: 1.7; }
|
package/dist/forms/types.d.ts
CHANGED
|
@@ -107,6 +107,10 @@ export interface FieldOption {
|
|
|
107
107
|
label: string;
|
|
108
108
|
}
|
|
109
109
|
export interface ValidationRules {
|
|
110
|
+
/** Use private Sonor attachment storage instead of the public media upload. */
|
|
111
|
+
private_attachments?: boolean;
|
|
112
|
+
/** Private document fields accept 1 to 4 files. */
|
|
113
|
+
max_files?: number;
|
|
110
114
|
min_length?: number;
|
|
111
115
|
max_length?: number;
|
|
112
116
|
min?: number;
|
package/dist/images/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from '../chunk-
|
|
1
|
+
export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from '../chunk-HWQPCZOX.js';
|
|
2
2
|
export { ManagedFavicon, getManagedFaviconUrl } from '../chunk-GW7GSBO7.js';
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
5
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-UYOE3HA4.js';
|
|
4
|
+
import '../chunk-P5PRR2BB.js';
|
|
5
|
+
import '../chunk-MNORERMF.js';
|
|
6
6
|
import '../chunk-PKBMQBKP.js';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { SITE_KIT_VERSION } from './chunk-
|
|
1
|
+
export { SITE_KIT_VERSION } from './chunk-MNORERMF.js';
|
|
2
2
|
import './chunk-PKBMQBKP.js';
|
|
@@ -1,13 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
* normalizeCampaignSlug is an inlined MIRROR of the Sonor API's campaign
|
|
5
|
-
* normalizer (the CANONICAL copy); keep the function body byte-identical.
|
|
6
|
-
* Both sides assert the same fixed vectors (this package's
|
|
7
|
-
* landing/contract.test.ts), so silent drift fails CI on either side.
|
|
8
|
-
*
|
|
9
|
-
* A slug normalized here always matches the server's canonical form, so the
|
|
10
|
-
* campaign a developer declares in code is exactly the identity the
|
|
11
|
-
* dashboard reports on.
|
|
12
|
-
*/
|
|
13
|
-
export declare function normalizeCampaignSlug(input?: string | null): string | null;
|
|
1
|
+
/** Compatibility entry. The shared contract owns campaign normalization. */
|
|
2
|
+
export { normalizeCampaignSlug } from '../contracts/campaign-normalize';
|
package/dist/landing/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
1
|
+
import '../chunk-BTHEQDN4.js';
|
|
2
|
+
export { LandingPage } from '../chunk-PAYCK7FC.js';
|
|
3
|
+
export { normalizeCampaignSlug } from '../chunk-3MJNBOUO.js';
|
|
4
|
+
export { landingPageMetadata } from '../chunk-JESLPEST.js';
|
|
3
5
|
import '../chunk-PKBMQBKP.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { Metadata } from 'next';
|
|
4
|
+
import { type ResolveServerApiConfigOptions } from '../server/server-fetch';
|
|
5
|
+
import { type PublishedFunnelPage } from '../contracts/funnels';
|
|
6
|
+
export interface GetPublishedFunnelPageOptions extends ResolveServerApiConfigOptions {
|
|
7
|
+
/** Explicit registered site host. No primary-domain or sibling-site fallback. */
|
|
8
|
+
site: string;
|
|
9
|
+
}
|
|
10
|
+
/** Current published pointer, uncached so pointer changes take effect at the next read. */
|
|
11
|
+
export declare function getPublishedFunnelPage(slug: string, options: GetPublishedFunnelPageOptions): Promise<PublishedFunnelPage | null>;
|
|
12
|
+
export declare function managedFunnelMetadata(page: PublishedFunnelPage): Metadata;
|
|
13
|
+
export interface ManagedFunnelPageProps {
|
|
14
|
+
page: PublishedFunnelPage;
|
|
15
|
+
/** Expiring owner dashboard preview only. Never fetches or mounts a live form. */
|
|
16
|
+
preview?: boolean;
|
|
17
|
+
/** Optional server transport overrides; never forwarded to browser markup. */
|
|
18
|
+
configOptions?: ResolveServerApiConfigOptions;
|
|
19
|
+
}
|
|
20
|
+
/** Server-rendered content plus the existing managed browser form and deferred analytics contract. */
|
|
21
|
+
export declare function ManagedFunnelPage({ page: input, preview, configOptions }: ManagedFunnelPageProps): Promise<React.JSX.Element>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React, { type ReactNode } from 'react';
|
|
2
|
+
import { type PublishedFunnelPage } from '../contracts/funnels';
|
|
3
|
+
export interface FunnelPageContentProps {
|
|
4
|
+
page: PublishedFunnelPage;
|
|
5
|
+
/** A live managed form supplied by the server adapter. Never used in a preview. */
|
|
6
|
+
conversion?: ReactNode;
|
|
7
|
+
/** Private dashboard preview. All conversion controls are inert. */
|
|
8
|
+
preview?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Bounded SSR layout for newsletter, requested-guide and inquiry content. */
|
|
11
|
+
export declare function FunnelPageContent({ page: input, conversion, preview }: FunnelPageContentProps): React.JSX.Element;
|
package/dist/landing/server.d.ts
CHANGED
|
@@ -29,3 +29,8 @@
|
|
|
29
29
|
*/
|
|
30
30
|
export { landingPageMetadata } from './metadata';
|
|
31
31
|
export { normalizeCampaignSlug } from './contract';
|
|
32
|
+
export { getPublishedFunnelPage, managedFunnelMetadata, ManagedFunnelPage } from './managed-server';
|
|
33
|
+
export type { GetPublishedFunnelPageOptions, ManagedFunnelPageProps } from './managed-server';
|
|
34
|
+
export { FunnelPageContent } from './managed';
|
|
35
|
+
export type { FunnelPageContentProps } from './managed';
|
|
36
|
+
export type { PublishedFunnelPage } from '../contracts/funnels';
|
package/dist/landing/server.js
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export { FunnelPageContent, ManagedFunnelPage, getPublishedFunnelPage, managedFunnelMetadata } from '../chunk-FXR5PJDL.js';
|
|
2
|
+
import '../chunk-PAYCK7FC.js';
|
|
3
|
+
export { normalizeCampaignSlug } from '../chunk-3MJNBOUO.js';
|
|
4
|
+
export { landingPageMetadata } from '../chunk-JESLPEST.js';
|
|
5
|
+
import '../chunk-XHYE24HU.js';
|
|
6
|
+
import '../chunk-DPYGC7WE.js';
|
|
7
|
+
import '../chunk-G5FD7UXK.js';
|
|
8
|
+
import '../chunk-C2FZBUSS.js';
|
|
9
|
+
import '../chunk-YC7ELZS3.js';
|
|
10
|
+
import '../chunk-VPZJ7ZTL.js';
|
|
11
|
+
import '../chunk-DXO6SBMD.js';
|
|
12
|
+
import '../chunk-CVADNHJ4.js';
|
|
13
|
+
import '../chunk-TYSIAWC3.js';
|
|
14
|
+
import '../chunk-HW7B43E5.js';
|
|
15
|
+
import '../chunk-NJCTQH2P.js';
|
|
16
|
+
import '../chunk-C7TLGL3R.js';
|
|
17
|
+
import '../chunk-MH2DSGC6.js';
|
|
18
|
+
import '../chunk-S22FSH7C.js';
|
|
19
|
+
import '../chunk-A4CC4ZG3.js';
|
|
3
20
|
import '../chunk-PKBMQBKP.js';
|