@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,21 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Injected via `<style>` in the server component output so consumers
|
|
5
|
-
* get a polished article with zero configuration.
|
|
6
|
-
*
|
|
7
|
-
* All colours use `--sk-*` CSS custom properties with `color-mix()` fallbacks
|
|
8
|
-
* that adapt to both light and dark host sites. The host can set:
|
|
9
|
-
*
|
|
10
|
-
* --sk-primary Brand accent (links, highlights)
|
|
11
|
-
* --sk-bg Page background
|
|
12
|
-
* --sk-bg-elevated Card / elevated surface background
|
|
13
|
-
* --sk-text-primary Main text
|
|
14
|
-
* --sk-text-secondary Subdued text
|
|
15
|
-
* --sk-text-tertiary Faint text / meta
|
|
16
|
-
* --sk-surface-border Subtle border color
|
|
17
|
-
*
|
|
18
|
-
* If none are set the defaults produce a clean neutral light-mode look.
|
|
19
|
-
*/
|
|
20
|
-
export declare const articleCss: string;
|
|
21
|
-
export declare const articleListCss: string;
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/article-styles';
|
|
@@ -1,12 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* captions, header associations, links and table semantics survive unchanged.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Single source of truth for default article table wrappers. Safe to call twice;
|
|
7
|
-
* already wrapped tables and HTML examples are left alone. This is a layout
|
|
8
|
-
* transform, not an HTML sanitizer: content still follows the host's trust policy.
|
|
9
|
-
*/
|
|
10
|
-
export declare function wrapArticleTables(html: string): string;
|
|
11
|
-
/** Native overflow only when content needs it; small tables retain their layout. */
|
|
12
|
-
export declare const articleTableCss: string;
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/article-tables';
|
|
@@ -1,13 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export interface ArticleArtwork {
|
|
4
|
-
src: string | undefined;
|
|
5
|
-
alt: string;
|
|
6
|
-
composed: boolean;
|
|
7
|
-
}
|
|
8
|
-
type ArtworkSource = Pick<Article, 'title' | 'featured_image' | 'featured_image_alt' | 'editorial_image' | 'editorial_image_alt'>;
|
|
9
|
-
/** Single source of truth for article artwork versus complete promotional cards. */
|
|
10
|
-
export declare function resolveArticleArtwork(post: ArtworkSource, placement?: 'article' | 'card'): ArticleArtwork;
|
|
11
|
-
/** Preserve generated text and graphics across every stock card surface. */
|
|
12
|
-
export declare function articleArtworkImageStyle(artwork: ArticleArtwork): CSSProperties | undefined;
|
|
13
|
-
export {};
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/artwork';
|
|
@@ -1,72 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Split out of `./server-core` on purpose. Everything here is a pure function:
|
|
5
|
-
* it maps an `ArticleAuthor` to schema objects and touches no env, no config,
|
|
6
|
-
* and no network. It only ever lived in `server-core` because the other author
|
|
7
|
-
* helpers there (`getAuthorBySlug`, `getAuthorPosts`) do fetch.
|
|
8
|
-
*
|
|
9
|
-
* `AuthorPage` is exported from the client-stamped `@sonordev/site-kit/articles`
|
|
10
|
-
* barrel (see `./index.ts`), so importing these from `server-core` dragged that
|
|
11
|
-
* whole server module — its `x-api-key` fetches included — into the browser
|
|
12
|
-
* bundle. Keeping the pure half here means `AuthorPage` can stay in the barrel
|
|
13
|
-
* without pulling a single line of server code with it.
|
|
14
|
-
*
|
|
15
|
-
* Anything added here must stay pure. If it needs an API key or a fetch, it
|
|
16
|
-
* belongs in `./server-core`, not in this file.
|
|
17
|
-
*
|
|
18
|
-
* Identity model (single source of truth for every author node the kit emits):
|
|
19
|
-
* - The author page is a `ProfilePage` whose `mainEntity` is the `Person`
|
|
20
|
-
* (Google's profile-page markup for author pages).
|
|
21
|
-
* - The `Person` carries one `@id` everywhere it appears (`authorEntityId`):
|
|
22
|
-
* the row's `entity_id` when the person has a cross-site identity (e.g.
|
|
23
|
-
* https://example.com/#person), else `<author profile URL>#person`.
|
|
24
|
-
* - Article bylines (`generateArticleAuthorNode`) reference that same `@id`,
|
|
25
|
-
* so an article, its author page and the person's own site describe one
|
|
26
|
-
* person, which is what a Knowledge Panel is built from.
|
|
27
|
-
*/
|
|
28
|
-
import type { ArticleAuthor } from './types';
|
|
29
|
-
import { type PublicationRoutingOptions } from './routes';
|
|
30
|
-
export type AuthorSchemaOptions = PublicationRoutingOptions & {
|
|
31
|
-
siteUrl?: string;
|
|
32
|
-
siteName?: string;
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Single source of truth for an author's Person `@id`.
|
|
36
|
-
*
|
|
37
|
-
* The row's `entity_id` (one id shared by every site that describes the
|
|
38
|
-
* person) wins. Otherwise the Person lives at `<profile URL>#person`. A
|
|
39
|
-
* relative profile URL gives no `@id`: an id must be absolute to mean the
|
|
40
|
-
* same thing on every page.
|
|
41
|
-
*/
|
|
42
|
-
export declare function authorEntityId(author: Pick<ArticleAuthor, 'entity_id'>, profileUrl?: string): string | undefined;
|
|
43
|
-
/**
|
|
44
|
-
* The bare `Person` for an author, with no `@context`, for embedding in a
|
|
45
|
-
* larger graph (an Organization's `founder`, an `@graph` array). Author pages
|
|
46
|
-
* want `generateAuthorSchema`, which wraps this in a `ProfilePage`.
|
|
47
|
-
*/
|
|
48
|
-
export declare function generateAuthorPersonSchema(author: ArticleAuthor, options?: AuthorSchemaOptions): Record<string, unknown>;
|
|
49
|
-
/**
|
|
50
|
-
* JSON-LD for an author page: a `ProfilePage` whose `mainEntity` is the
|
|
51
|
-
* author's `Person`. Render it once per author page (`AuthorPage` does, unless
|
|
52
|
-
* its `jsonLd` prop is false).
|
|
53
|
-
*/
|
|
54
|
-
export declare function generateAuthorSchema(author: ArticleAuthor, options?: AuthorSchemaOptions): object;
|
|
55
|
-
/**
|
|
56
|
-
* The `author` node for article JSON-LD. Single source of truth for bylines:
|
|
57
|
-
* generateArticleSchema, generateClusterArticleSchema and stored schema_json
|
|
58
|
-
* (via withArticleAuthorIdentity) all route through here.
|
|
59
|
-
*
|
|
60
|
-
* Links to an author page only when one is known to exist: the row's
|
|
61
|
-
* `author_page_url`, or the site declaring `authorPages` in its routing. A
|
|
62
|
-
* bare string byline stays a named Person.
|
|
63
|
-
*/
|
|
64
|
-
export declare function generateArticleAuthorNode(author: ArticleAuthor | string | null | undefined, options?: AuthorSchemaOptions): Record<string, unknown> | undefined;
|
|
65
|
-
/**
|
|
66
|
-
* Attach the author's identity to an article node from stored schema_json
|
|
67
|
-
* (built by Signal at publish time, frozen in the row). Adds `@id` and `url`
|
|
68
|
-
* from generateArticleAuthorNode when the stored byline is a Person with the
|
|
69
|
-
* same name and lacks them; stored values always win and nothing else in the
|
|
70
|
-
* node changes. Non-article nodes pass through untouched.
|
|
71
|
-
*/
|
|
72
|
-
export declare function withArticleAuthorIdentity(node: unknown, author: ArticleAuthor | string | null | undefined, options?: AuthorSchemaOptions): unknown;
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/author-schema';
|
|
@@ -1,14 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
label: string;
|
|
4
|
-
href: string;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Single source of truth for author social display.
|
|
8
|
-
*
|
|
9
|
-
* The real blog_authors columns are linkedin_url / twitter_url / website_url
|
|
10
|
-
* (E-E-A-T fields); `social_links` / `website` are the legacy shape that no
|
|
11
|
-
* API response ever carried. Real columns win; legacy handles get their host
|
|
12
|
-
* prefixed unless they are already full URLs.
|
|
13
|
-
*/
|
|
14
|
-
export declare function getAuthorSocialLinks(author: Pick<ArticleAuthor, 'linkedin_url' | 'twitter_url' | 'website_url' | 'website' | 'social_links'>): AuthorSocialLink[];
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/author-social';
|
|
@@ -1,17 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Pure (no `server-only` chain) so it is unit-testable and safe to reuse.
|
|
5
|
-
* Source of truth for turning a stored excerpt into display-safe prose.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Turn a stored excerpt into something safe to put in a meta description,
|
|
9
|
-
* a schema `description`, or an RSS `<description>`.
|
|
10
|
-
*
|
|
11
|
-
* The AI article pipeline stores content as JSON sections
|
|
12
|
-
* (`{"heading": "## ...", "content": "## ...\n\nIf you're asking **how**..."}`)
|
|
13
|
-
* and that value can ship verbatim into <meta name="description">, leaving a
|
|
14
|
-
* SERP snippet of raw JSON with markdown asterisks and literal \n. Parse the
|
|
15
|
-
* sections out, strip markdown, and cap at a sentence boundary.
|
|
16
|
-
*/
|
|
17
|
-
export declare function sanitizeExcerpt(raw: string | undefined | null, maxLength?: number): string;
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/excerpt';
|
package/dist/articles/index.d.ts
CHANGED
|
@@ -1,79 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Complete article integration for Sonor-managed content.
|
|
5
|
-
* Create posts in the Sonor dashboard, automatically embedded in your site.
|
|
6
|
-
*
|
|
7
|
-
* Async server components (PublicationLayout, ArticleList, Article, PublicationSidebar,
|
|
8
|
-
* RelatedPosts, the *Page helpers) come from `articles/server-ui`. This entry is
|
|
9
|
-
* 'use client'-stamped, so importing them from here hands Next an async
|
|
10
|
-
* component across a client boundary and the route 500s in production.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```tsx
|
|
14
|
-
* // Publication index page — both from server-ui; this barrel is for client components only
|
|
15
|
-
* import { ArticleList, PublicationLayout } from '@sonordev/site-kit/articles/server-ui'
|
|
16
|
-
*
|
|
17
|
-
* export default function PublicationPage() {
|
|
18
|
-
* return (
|
|
19
|
-
* <PublicationLayout hero={{ title: 'Blog', subtitle: 'Latest articles' }}>
|
|
20
|
-
* <ArticleList showCategoryFilter showPagination />
|
|
21
|
-
* </PublicationLayout>
|
|
22
|
-
* )
|
|
23
|
-
* }
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```tsx
|
|
28
|
-
* // Single post page: UI from server-ui, data/metadata from server
|
|
29
|
-
* import { Article } from '@sonordev/site-kit/articles/server-ui'
|
|
30
|
-
* import { generateArticleMetadata, generateArticleStaticParams } from '@sonordev/site-kit/articles/server'
|
|
31
|
-
*
|
|
32
|
-
* export const generateStaticParams = generateArticleStaticParams
|
|
33
|
-
* export async function generateMetadata({ params }) {
|
|
34
|
-
* return generateArticleMetadata(params.slug, { siteName: 'My Site' })
|
|
35
|
-
* }
|
|
36
|
-
*
|
|
37
|
-
* export default function Post({ params }) {
|
|
38
|
-
* return <Article slug={params.slug} showRelated showToc />
|
|
39
|
-
* }
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
|
-
export type { ArticleServerProps, ArticleStyles } from './Article';
|
|
43
|
-
export type { ArticleListServerProps, ArticleListStyles } from './ArticleList';
|
|
44
|
-
export type { PublicationSidebarProps } from './PublicationSidebar';
|
|
45
|
-
export { NewsletterWidget } from './NewsletterWidget';
|
|
46
|
-
export type { NewsletterWidgetProps } from './NewsletterWidget';
|
|
47
|
-
export type { PublicationLayoutProps, PublicationPageProps, ArticlePageProps, CategoryPageProps } from './PublicationLayout';
|
|
48
|
-
export { AuthorCard } from './AuthorCard';
|
|
49
|
-
export { AuthorPage } from './AuthorPage';
|
|
50
|
-
export { TableOfContents } from './TableOfContents';
|
|
51
|
-
export { ServiceCallout, ServiceCallouts } from './ServiceCallout';
|
|
52
|
-
export type { ServiceCalloutProps } from './ServiceCallout';
|
|
53
|
-
export { ArticleFAQ } from './ArticleFAQ';
|
|
54
|
-
export type { ArticleEditorialPhoto } from './types';
|
|
55
|
-
export type { ArticleFAQProps, FaqItem } from './ArticleFAQ';
|
|
56
|
-
export { ClusterNavigation } from './ClusterNavigation';
|
|
57
|
-
export type { ClusterNavigationProps } from './ClusterNavigation';
|
|
58
|
-
/**
|
|
59
|
-
* `ClusterLandingPage` is deliberately NOT re-exported here — import it from
|
|
60
|
-
* `@sonordev/site-kit/articles/server-ui`.
|
|
61
|
-
*
|
|
62
|
-
* This barrel is stamped `'use client'` at build time (it is listed in
|
|
63
|
-
* `CLIENT_ENTRIES`, `src/shared/build-entries.ts`), so every module it reaches
|
|
64
|
-
* is client code by declaration. `ClusterLandingPage` is an async component that
|
|
65
|
-
* awaits `getTopicCluster` from `./server-core`, so exporting it from here put
|
|
66
|
-
* that module's `x-api-key` fetch into the browser bundle (confirmed in a real
|
|
67
|
-
* site's build, in `.next/static/chunks/`). It also could never have
|
|
68
|
-
* worked as a client component: async components are server-only.
|
|
69
|
-
*
|
|
70
|
-
* The type stays — `export type` is erased at build time and reaches no runtime
|
|
71
|
-
* module, so it keeps `import type { ClusterLandingPageProps }` working for
|
|
72
|
-
* existing consumers.
|
|
73
|
-
*/
|
|
74
|
-
export type { ClusterLandingPageProps } from './ClusterLandingPage';
|
|
75
|
-
export * from './types';
|
|
76
|
-
export { articleCategorySlug, createPublicationRoutes, resolveArticleUrl, resolvePublicationUrl } from './routes';
|
|
77
|
-
export type { ArticleRoutePost, PublicationRoutingOptions } from './routes';
|
|
78
|
-
export { resolveArticleArtwork } from './artwork';
|
|
79
|
-
export { addExternalLinkTargets, linkClassificationHost, normalizeSiteHost, resolvePublicationSiteUrl, } from './processArticleHtml';
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/index';
|
package/dist/articles/index.js
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { NewsletterShell } from '../chunk-
|
|
3
|
-
export { ArticleFAQ } from '../chunk-
|
|
4
|
-
import { getAuthorSocialLinks, readingTimeMinutes } from '../chunk-
|
|
5
|
-
export { ClusterNavigation, ServiceCallout, ServiceCallouts } from '../chunk-
|
|
6
|
-
import '../chunk-
|
|
7
|
-
export { addExternalLinkTargets, linkClassificationHost, normalizeSiteHost, resolvePublicationSiteUrl } from '../chunk-
|
|
8
|
-
import { generateAuthorSchema, resolveArticleArtwork, articleArtworkImageStyle } from '../chunk-
|
|
9
|
-
export { resolveArticleArtwork } from '../chunk-
|
|
10
|
-
import
|
|
11
|
-
|
|
2
|
+
import { NewsletterShell } from '../chunk-LBDWAXAO.js';
|
|
3
|
+
export { ArticleFAQ } from '../chunk-BVB5FBAA.js';
|
|
4
|
+
import { getAuthorSocialLinks, readingTimeMinutes } from '../chunk-BC7JMY4Z.js';
|
|
5
|
+
export { ClusterNavigation, ServiceCallout, ServiceCallouts } from '../chunk-BC7JMY4Z.js';
|
|
6
|
+
import '../chunk-DJAYFHVF.js';
|
|
7
|
+
export { addExternalLinkTargets, linkClassificationHost, normalizeSiteHost, resolvePublicationSiteUrl } from '../chunk-5D7ZISUP.js';
|
|
8
|
+
import { generateAuthorSchema, resolveArticleArtwork, articleArtworkImageStyle } from '../chunk-SNRE3ZVZ.js';
|
|
9
|
+
export { resolveArticleArtwork } from '../chunk-SNRE3ZVZ.js';
|
|
10
|
+
import '../chunk-H72ZFO3F.js';
|
|
11
|
+
import { createPublicationRoutes } from '../chunk-4K735O3J.js';
|
|
12
|
+
export { articleCategorySlug, createPublicationRoutes, resolveArticleUrl, resolvePublicationUrl } from '../chunk-4K735O3J.js';
|
|
12
13
|
import { safeJsonLd } from '../chunk-4KZ6W3ZH.js';
|
|
14
|
+
import '../chunk-MJP63SSS.js';
|
|
13
15
|
import '../chunk-YVKRYQRG.js';
|
|
16
|
+
import '../chunk-FESKKJAS.js';
|
|
17
|
+
import '../chunk-A4CC4ZG3.js';
|
|
18
|
+
import '../chunk-W7OPEMGJ.js';
|
|
14
19
|
import '../chunk-PKBMQBKP.js';
|
|
15
20
|
import React, { useState, Suspense, useEffect } from 'react';
|
|
16
21
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
17
22
|
|
|
18
|
-
var ManagedNewsletterForm = React.lazy(() => import('../ManagedNewsletterForm-
|
|
23
|
+
var ManagedNewsletterForm = React.lazy(() => import('../ManagedNewsletterForm-NFNF33V3.js'));
|
|
19
24
|
function NewsletterWidget({
|
|
20
25
|
title = "Subscribe to Our Newsletter",
|
|
21
26
|
description = "Get the latest posts delivered straight to your inbox.",
|
|
@@ -1,46 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* server helpers in server-core fetch the posts and hand them here, so the XML
|
|
4
|
-
* rules can be tested without a network.
|
|
5
|
-
*
|
|
6
|
-
* News sitemap rules (https://developers.google.com/search/docs/crawling-indexing/sitemaps/news-sitemap):
|
|
7
|
-
* only articles published in the last two days, at most 1,000 URLs, each with
|
|
8
|
-
* a publication name, language and publication date. Older articles belong in
|
|
9
|
-
* the ordinary sitemap, which already lists them.
|
|
10
|
-
*/
|
|
11
|
-
import { type PublicationRoutingOptions, type ArticleRoutePost } from './routes';
|
|
12
|
-
/** Google only reads articles from the last two days in a News sitemap. */
|
|
13
|
-
export declare const NEWS_SITEMAP_WINDOW_MS: number;
|
|
14
|
-
/** Google's cap per News sitemap. */
|
|
15
|
-
export declare const NEWS_SITEMAP_MAX_URLS = 1000;
|
|
16
|
-
/**
|
|
17
|
-
* Items a feed carries by default. Feeds hold each post's full HTML, so a
|
|
18
|
-
* 100-post feed ran past half a megabyte, which is where some readers and
|
|
19
|
-
* aggregators stop fetching. Readers poll often; 20 recent items is the
|
|
20
|
-
* common convention, and older posts stay in the sitemap.
|
|
21
|
-
*/
|
|
22
|
-
export declare const FEED_DEFAULT_ITEMS = 20;
|
|
23
|
-
export interface NewsSitemapPost extends ArticleRoutePost {
|
|
24
|
-
title: string;
|
|
25
|
-
published_at?: string | null;
|
|
26
|
-
}
|
|
27
|
-
export interface NewsSitemapOptions extends PublicationRoutingOptions {
|
|
28
|
-
siteUrl: string;
|
|
29
|
-
/** The publication name, exactly as it appears on the articles (e.g. "The Journal by Example Co."). */
|
|
30
|
-
publicationName: string;
|
|
31
|
-
/** ISO 639 language code. Defaults to "en". */
|
|
32
|
-
language?: string;
|
|
33
|
-
}
|
|
34
|
-
export declare function escapeXml(text: string): string;
|
|
35
|
-
/**
|
|
36
|
-
* Wrap HTML in CDATA. A literal `]]>` inside the post would close the section
|
|
37
|
-
* early and break the whole feed, so it's split across two sections.
|
|
38
|
-
*/
|
|
39
|
-
export declare function cdata(html: string): string;
|
|
40
|
-
/** The posts a News sitemap may list: published in the window, newest first. */
|
|
41
|
-
export declare function recentNewsPosts<T extends NewsSitemapPost>(posts: T[], now?: Date): T[];
|
|
42
|
-
/**
|
|
43
|
-
* Build a Google News sitemap. With no post in the window it's a valid, empty
|
|
44
|
-
* urlset, which Google accepts; it fills again on the next publish.
|
|
45
|
-
*/
|
|
46
|
-
export declare function buildNewsSitemapXml(posts: NewsSitemapPost[], options: NewsSitemapOptions, now?: Date): string;
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/news-sitemap';
|
|
@@ -1,34 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Server-safe string transforms only (no DOM).
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* The host `addExternalLinkTargets` compares links against to decide whether a
|
|
7
|
-
* link is internal (same tab) or external (`target="_blank"`). Lowercased,
|
|
8
|
-
* leading `www.` stripped, so `www.example.com` and `example.com` count as the
|
|
9
|
-
* same site; returns '' for anything unparseable.
|
|
10
|
-
*
|
|
11
|
-
* NOT the multi-site host normalizer. That is `normalizeSiteHost` in
|
|
12
|
-
* `sites/normalize`, which keeps `www.` because `www.example.com` and
|
|
13
|
-
* `example.com` can be different sub-sites of one Sonor project. This used to
|
|
14
|
-
* share that name, so the two were easy to swap by accident.
|
|
15
|
-
*/
|
|
16
|
-
export declare function linkClassificationHost(siteUrl: string): string;
|
|
17
|
-
/**
|
|
18
|
-
* @deprecated Renamed to {@link linkClassificationHost} (same behavior: strips
|
|
19
|
-
* `www.`). It shared a name with the multi-site `normalizeSiteHost` from
|
|
20
|
-
* `sites/normalize`, which keeps `www.`. Kept so existing imports from
|
|
21
|
-
* `@sonordev/site-kit/articles` still work.
|
|
22
|
-
*/
|
|
23
|
-
export declare const normalizeSiteHost: typeof linkClassificationHost;
|
|
24
|
-
/**
|
|
25
|
-
* Resolve canonical site URL for link classification.
|
|
26
|
-
* Pass `explicit` from props when env vars are not set (e.g. non-Vercel hosts).
|
|
27
|
-
*/
|
|
28
|
-
export declare function resolvePublicationSiteUrl(explicit?: string): string;
|
|
29
|
-
/**
|
|
30
|
-
* Add `target="_blank"` and `rel="noopener noreferrer"` to external http(s) links.
|
|
31
|
-
* Same registrable host (with or without `www`) is treated as internal.
|
|
32
|
-
* Skips anchors that already set `target`.
|
|
33
|
-
*/
|
|
34
|
-
export declare function addExternalLinkTargets(html: string, siteUrl: string): string;
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/processArticleHtml';
|
|
@@ -1,26 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
apiUrl: string;
|
|
4
|
-
apiKey: string;
|
|
5
|
-
/** Sub-site host override. Omit to resolve from NEXT_PUBLIC_SITE_URL. */
|
|
6
|
-
site?: string;
|
|
7
|
-
}
|
|
8
|
-
/** GET /public/articles/posts/:slug — null when missing or on any failure. */
|
|
9
|
-
export declare function fetchArticleBySlug({ apiUrl, apiKey, site }: ArticleReadConfig, slug: string): Promise<Article | null>;
|
|
10
|
-
/** GET /public/articles/categories — [] on any failure. */
|
|
11
|
-
export declare function fetchArticleCategories({ apiUrl, apiKey, site }: ArticleReadConfig): Promise<ArticleCategory[]>;
|
|
12
|
-
/**
|
|
13
|
-
* POST /public/articles/related — [] on any failure.
|
|
14
|
-
*
|
|
15
|
-
* `/public/articles/*`, not `/api/public/articles/*`: public-article.controller is one of
|
|
16
|
-
* only two public controllers whose @Controller() omits the `api/` segment.
|
|
17
|
-
* The body is snake_case `current_post_id` (the controller looks the post up
|
|
18
|
-
* by id — there is no slug path), and `site` rides in the body because this is
|
|
19
|
-
* the one article read that isn't a GET.
|
|
20
|
-
*
|
|
21
|
-
* `revalidate` is optional so <RelatedPosts>, which never set a fetch cache
|
|
22
|
-
* lifetime, keeps rendering exactly as it did.
|
|
23
|
-
*/
|
|
24
|
-
export declare function fetchRelatedArticles({ apiUrl, apiKey, site }: ArticleReadConfig, currentPostId: string, limit: number, cache?: {
|
|
25
|
-
revalidate?: number;
|
|
26
|
-
}): Promise<Article[]>;
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/public-reads';
|
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Single source of truth for reading-time display.
|
|
4
|
-
*
|
|
5
|
-
* The DB/API column is `reading_time` (blog_posts) — `reading_time_minutes`
|
|
6
|
-
* never existed server-side and exists on the type only for callers that
|
|
7
|
-
* pre-map their own data. Every "X min read" chip resolves through here.
|
|
8
|
-
*/
|
|
9
|
-
export declare function readingTimeMinutes(post: Pick<Article, 'reading_time' | 'reading_time_minutes'>): number | null;
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/reading-time';
|
|
@@ -1,52 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export
|
|
3
|
-
slug: string;
|
|
4
|
-
category?: string | {
|
|
5
|
-
slug?: string;
|
|
6
|
-
name?: string;
|
|
7
|
-
} | null;
|
|
8
|
-
canonical_url?: string | null;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Where a publication lives when a site doesn't say. A site whose articles
|
|
12
|
-
* already live at another path (/article, /insights, /theforge) passes basePath;
|
|
13
|
-
* changing a live URL is an SEO decision, never a default's.
|
|
14
|
-
*/
|
|
15
|
-
export declare const DEFAULT_PUBLICATION_PATH = "/articles";
|
|
16
|
-
export interface PublicationRoutingOptions {
|
|
17
|
-
/** Publication root, e.g. /theforge or /news. Defaults to DEFAULT_PUBLICATION_PATH (/articles). */
|
|
18
|
-
basePath?: string;
|
|
19
|
-
/** Use /publication/category/post instead of /publication/post. */
|
|
20
|
-
includeCategoryInPath?: boolean;
|
|
21
|
-
/** Fallback category for partial cluster records. */
|
|
22
|
-
category?: string;
|
|
23
|
-
/** A custom local article path. Receives the post's slug and category. */
|
|
24
|
-
postPath?: (post: ArticleRoutePost) => string;
|
|
25
|
-
/** A custom category destination, for example /theforge?category=guides. */
|
|
26
|
-
categoryPath?: (slug: string) => string;
|
|
27
|
-
/**
|
|
28
|
-
* Whether this site serves author pages. `true` means they live at the
|
|
29
|
-
* default `<publication>/author/<slug>`; a function gives a custom path, for
|
|
30
|
-
* example ``(slug) => `/author/${slug}` `` when author pages sit at the site
|
|
31
|
-
* root. Article JSON-LD links bylines to author pages ONLY when this is set
|
|
32
|
-
* (or the author row has `author_page_url`), because most sites have none
|
|
33
|
-
* and a byline URL that 404s is worse than no URL.
|
|
34
|
-
*/
|
|
35
|
-
authorPages?: boolean | ((slug: string) => string);
|
|
36
|
-
}
|
|
37
|
-
export declare function articleCategorySlug(category: ArticleRoutePost['category']): string;
|
|
38
|
-
/** Single source of truth for publication paths. Custom routes never change OG artwork. */
|
|
39
|
-
export declare function createPublicationRoutes(options?: PublicationRoutingOptions): {
|
|
40
|
-
index: string;
|
|
41
|
-
post(post: ArticleRoutePost): string;
|
|
42
|
-
category(slug: string): string;
|
|
43
|
-
cluster: (slug: string) => string;
|
|
44
|
-
author: (slug: string) => string;
|
|
45
|
-
rss: string;
|
|
46
|
-
atom: string;
|
|
47
|
-
};
|
|
48
|
-
export declare function resolvePublicationUrl(path: string, siteUrl?: string): string;
|
|
49
|
-
/** Metadata, feeds, sitemaps and generated schemas agree on a supplied canonical. */
|
|
50
|
-
export declare function resolveArticleUrl(post: ArticleRoutePost, options?: PublicationRoutingOptions & {
|
|
51
|
-
siteUrl?: string;
|
|
52
|
-
}): string;
|
|
1
|
+
/** @deprecated Import from @sonordev/press-kit instead. Compatibility build uses the same canonical source. */
|
|
2
|
+
export * from '../press-kit/articles/routes';
|