@krantho/ui-react 0.0.0-stage → 1.0.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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/client/CMSImage.d.ts +4 -0
  3. package/dist/components/client/CMSImage.d.ts.map +1 -0
  4. package/dist/components/client/CMSImage.js +23 -0
  5. package/dist/components/client/CMSImage.js.map +1 -0
  6. package/dist/components/client/CMSMarkdown.d.ts +4 -0
  7. package/dist/components/client/CMSMarkdown.d.ts.map +1 -0
  8. package/dist/components/client/CMSMarkdown.js +15 -0
  9. package/dist/components/client/CMSMarkdown.js.map +1 -0
  10. package/dist/components/client/CMSText.d.ts +4 -0
  11. package/dist/components/client/CMSText.d.ts.map +1 -0
  12. package/dist/components/client/CMSText.js +15 -0
  13. package/dist/components/client/CMSText.js.map +1 -0
  14. package/dist/components/server/CMSImageServer.d.ts +4 -0
  15. package/dist/components/server/CMSImageServer.d.ts.map +1 -0
  16. package/dist/components/server/CMSImageServer.js +27 -0
  17. package/dist/components/server/CMSImageServer.js.map +1 -0
  18. package/dist/components/server/CMSMarkdownServer.d.ts +4 -0
  19. package/dist/components/server/CMSMarkdownServer.d.ts.map +1 -0
  20. package/dist/components/server/CMSMarkdownServer.js +24 -0
  21. package/dist/components/server/CMSMarkdownServer.js.map +1 -0
  22. package/dist/components/server/CMSTextServer.d.ts +4 -0
  23. package/dist/components/server/CMSTextServer.d.ts.map +1 -0
  24. package/dist/components/server/CMSTextServer.js +22 -0
  25. package/dist/components/server/CMSTextServer.js.map +1 -0
  26. package/dist/components/utils.d.ts +4 -0
  27. package/dist/components/utils.d.ts.map +1 -0
  28. package/dist/components/utils.js +18 -0
  29. package/dist/components/utils.js.map +1 -0
  30. package/dist/context.d.ts +4 -0
  31. package/dist/context.d.ts.map +1 -0
  32. package/dist/context.js +12 -0
  33. package/dist/context.js.map +1 -0
  34. package/dist/hooks/content-context.d.ts +10 -0
  35. package/dist/hooks/content-context.d.ts.map +1 -0
  36. package/dist/hooks/content-context.js +12 -0
  37. package/dist/hooks/content-context.js.map +1 -0
  38. package/dist/hooks/use-cms-config.d.ts +3 -0
  39. package/dist/hooks/use-cms-config.d.ts.map +1 -0
  40. package/dist/hooks/use-cms-config.js +12 -0
  41. package/dist/hooks/use-cms-config.js.map +1 -0
  42. package/dist/hooks/use-content.d.ts +3 -0
  43. package/dist/hooks/use-content.d.ts.map +1 -0
  44. package/dist/hooks/use-content.js +79 -0
  45. package/dist/hooks/use-content.js.map +1 -0
  46. package/dist/index.d.ts +10 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +13 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/provider.d.ts +9 -0
  51. package/dist/provider.d.ts.map +1 -0
  52. package/dist/provider.js +25 -0
  53. package/dist/provider.js.map +1 -0
  54. package/dist/server/cms-context.d.ts +19 -0
  55. package/dist/server/cms-context.d.ts.map +1 -0
  56. package/dist/server/cms-context.js +45 -0
  57. package/dist/server/cms-context.js.map +1 -0
  58. package/dist/server/content-loader.d.ts +26 -0
  59. package/dist/server/content-loader.d.ts.map +1 -0
  60. package/dist/server/content-loader.js +110 -0
  61. package/dist/server/content-loader.js.map +1 -0
  62. package/dist/server/seo-jsonld.d.ts +27 -0
  63. package/dist/server/seo-jsonld.d.ts.map +1 -0
  64. package/dist/server/seo-jsonld.js +45 -0
  65. package/dist/server/seo-jsonld.js.map +1 -0
  66. package/dist/server/seo-resolver.d.ts +32 -0
  67. package/dist/server/seo-resolver.d.ts.map +1 -0
  68. package/dist/server/seo-resolver.js +84 -0
  69. package/dist/server/seo-resolver.js.map +1 -0
  70. package/dist/server.d.ts +11 -0
  71. package/dist/server.d.ts.map +1 -0
  72. package/dist/server.js +12 -0
  73. package/dist/server.js.map +1 -0
  74. package/dist/types.d.ts +87 -0
  75. package/dist/types.d.ts.map +1 -0
  76. package/dist/types.js +9 -0
  77. package/dist/types.js.map +1 -0
  78. package/package.json +45 -3
  79. package/README.md +0 -3
@@ -0,0 +1,45 @@
1
+ import { cache } from 'react';
2
+ import { getServerLoader, loadCollection, loadContent, loadSummaries } from './content-loader.js';
3
+ /**
4
+ * Load the published version of a document. The returned `fields` is
5
+ * `Record<string, unknown>` — callers can narrow to `Record<string, string>`
6
+ * when they know the content shape. Throws a 404 `NetworkError` when the
7
+ * document has no published version.
8
+ */
9
+ export const getCMSContent = cache(async (collection, slug, options) => {
10
+ return loadContent({ collection, slug, locale: options?.locale }, options);
11
+ });
12
+ /** The slugs of the published documents in a collection */
13
+ export const getCMSSlugs = cache(async (collection, locale) => {
14
+ const docs = await getServerLoader().listPublishedSummaries(collection, locale);
15
+ return docs.map((doc) => doc.slug);
16
+ });
17
+ /** Every published document in a collection */
18
+ export const getAllCMSContent = cache(async (collection, options) => {
19
+ try {
20
+ return await loadCollection(collection, options?.locale, options);
21
+ }
22
+ catch (error) {
23
+ if (process.env.NODE_ENV === 'development') {
24
+ console.warn(`Failed to load the ${collection} collection:`, error);
25
+ }
26
+ return [];
27
+ }
28
+ });
29
+ /**
30
+ * The published documents of a collection without their bodies: the fields a
31
+ * list, a card or a navigation shows. Nothing is rendered; a page that shows a
32
+ * document's body reads `getAllCMSContent` or `getCMSContent`.
33
+ */
34
+ export const getAllCMSSummaries = cache(async (collection, options) => {
35
+ try {
36
+ return await loadSummaries(collection, options?.locale);
37
+ }
38
+ catch (error) {
39
+ if (process.env.NODE_ENV === 'development') {
40
+ console.warn(`Failed to load the ${collection} collection:`, error);
41
+ }
42
+ return [];
43
+ }
44
+ });
45
+ //# sourceMappingURL=cms-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-context.js","sourceRoot":"","sources":["../../src/server/cms-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAE7B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEjG;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAChC,KAAK,EAAE,UAAkB,EAAE,IAAY,EAAE,OAA2B,EAAuB,EAAE;IAC3F,OAAO,WAAW,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,CAAA;AAC5E,CAAC,CACF,CAAA;AAED,2DAA2D;AAC3D,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAC9B,KAAK,EAAE,UAAkB,EAAE,MAA2B,EAAqB,EAAE;IAC3E,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAC,sBAAsB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;IAC/E,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AACpC,CAAC,CACF,CAAA;AAED,+CAA+C;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CACnC,KAAK,EAAE,UAAkB,EAAE,OAA2B,EAAyB,EAAE;IAC/E,IAAI,CAAC;QACH,OAAO,MAAM,cAAc,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IACnE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,sBAAsB,UAAU,cAAc,EAAE,KAAK,CAAC,CAAA;QACrE,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC,CACF,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CACrC,KAAK,EAAE,UAAkB,EAAE,OAA2B,EAAyB,EAAE;IAC/E,IAAI,CAAC;QACH,OAAO,MAAM,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,sBAAsB,UAAU,cAAc,EAAE,KAAK,CAAC,CAAA;QACrE,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC,CACF,CAAA"}
@@ -0,0 +1,26 @@
1
+ import type { ContentRef, IPublishedContentLoader, IPublishedSeoLoader } from '@krantho/core';
2
+ import type { CMSContent, CMSSummary, ContentLoaderOptions } from '../types';
3
+ /**
4
+ * What server components read through: published content, and the pages' SEO
5
+ * when the loader serves it (`createContentLoader()` does). Without SEO, the
6
+ * resolvers fall back to content fields and render no JSON-LD.
7
+ */
8
+ export type ServerContentLoader = IPublishedContentLoader & Partial<IPublishedSeoLoader>;
9
+ /** The loader server components read through */
10
+ export declare function getServerLoader(): ServerContentLoader;
11
+ /**
12
+ * Set the loader server components read through — `createContentLoader()` from
13
+ * `@krantho/server` (re-exported by the framework adapters). Pages read only
14
+ * the live (published) version of each document.
15
+ */
16
+ export declare function initServerLoader(loader: ServerContentLoader): void;
17
+ /**
18
+ * Load the live version of a document. A document with no published version
19
+ * — never published, unpublished or deleted — is a 404.
20
+ */
21
+ export declare function loadContent(ref: ContentRef, options?: ContentLoaderOptions): Promise<CMSContent>;
22
+ /** Load the live version of every published document in a collection */
23
+ export declare function loadCollection(collection: string, locale?: string | undefined, options?: ContentLoaderOptions): Promise<CMSContent[]>;
24
+ /** Load the live version of every published document in a collection, without bodies: nothing is rendered */
25
+ export declare function loadSummaries(collection: string, locale?: string | undefined): Promise<CMSSummary[]>;
26
+ //# sourceMappingURL=content-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-loader.d.ts","sourceRoot":"","sources":["../../src/server/content-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,uBAAuB,EACvB,mBAAmB,EAEpB,MAAM,eAAe,CAAA;AAEtB,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE5E;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,uBAAuB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAIxF,gDAAgD;AAChD,wBAAgB,eAAe,IAAI,mBAAmB,CAOrD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAElE;AAiED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,UAAU,CAAC,CAWrB;AAED,wEAAwE;AACxE,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,UAAU,EAAE,CAAC,CAWvB;AAED,6GAA6G;AAC7G,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAC1B,OAAO,CAAC,UAAU,EAAE,CAAC,CAiBvB"}
@@ -0,0 +1,110 @@
1
+ import { NetworkError, renderContent } from '@krantho/core';
2
+ let serverLoader = null;
3
+ /** The loader server components read through */
4
+ export function getServerLoader() {
5
+ if (!serverLoader) {
6
+ throw new Error('Server content loader not initialized. Call initServerLoader() with a content loader.');
7
+ }
8
+ return serverLoader;
9
+ }
10
+ /**
11
+ * Set the loader server components read through — `createContentLoader()` from
12
+ * `@krantho/server` (re-exported by the framework adapters). Pages read only
13
+ * the live (published) version of each document.
14
+ */
15
+ export function initServerLoader(loader) {
16
+ serverLoader = loader;
17
+ }
18
+ function generateExcerpt(sections, rawContent, length = 160) {
19
+ const sectionKeys = Object.keys(sections);
20
+ const firstKey = sectionKeys[0];
21
+ const firstSection = firstKey ? sections[firstKey] : undefined;
22
+ const source = firstSection ?? rawContent;
23
+ const plainText = source
24
+ .replace(/<[^>]+>/g, '')
25
+ .replace(/#{1,6}\s+/g, '')
26
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
27
+ .replace(/[*_`~]/g, '')
28
+ .replace(/\n+/g, ' ')
29
+ .trim();
30
+ if (plainText.length <= length)
31
+ return plainText;
32
+ const truncated = plainText.substring(0, length);
33
+ const lastSpace = truncated.lastIndexOf(' ');
34
+ return truncated.substring(0, lastSpace) + '...';
35
+ }
36
+ async function toCMSContent(doc, options, preview) {
37
+ const { processMarkdown = true, extractSections = true, generateExcerpt: shouldGenerateExcerpt = true, excerptLength = 160, } = options;
38
+ const rendered = await renderContent(doc.fields, doc.body);
39
+ const sections = extractSections ? rendered.sections : {};
40
+ return {
41
+ collection: doc.collection,
42
+ slug: doc.slug,
43
+ locale: doc.locale,
44
+ fields: doc.fields,
45
+ html: processMarkdown ? rendered.html : rendered.content,
46
+ rawContent: rendered.content,
47
+ sections,
48
+ excerpt: shouldGenerateExcerpt
49
+ ? generateExcerpt(sections, rendered.content, excerptLength)
50
+ : undefined,
51
+ preview,
52
+ };
53
+ }
54
+ function loadFailure(error) {
55
+ if (error instanceof NetworkError)
56
+ return error;
57
+ return new NetworkError(error instanceof Error ? error.message : 'Unknown error during content loading', 500);
58
+ }
59
+ /**
60
+ * Load the live version of a document. A document with no published version
61
+ * — never published, unpublished or deleted — is a 404.
62
+ */
63
+ export async function loadContent(ref, options = {}) {
64
+ const loader = getServerLoader();
65
+ try {
66
+ const doc = await loader.getPublished(ref);
67
+ if (!doc) {
68
+ throw new NetworkError(`No published content: ${ref.collection}/${ref.slug}`, 404);
69
+ }
70
+ return await toCMSContent(doc, options, await loader.isPreview());
71
+ }
72
+ catch (error) {
73
+ throw loadFailure(error);
74
+ }
75
+ }
76
+ /** Load the live version of every published document in a collection */
77
+ export async function loadCollection(collection, locale, options = {}) {
78
+ const loader = getServerLoader();
79
+ try {
80
+ const [docs, preview] = await Promise.all([
81
+ loader.listPublished(collection, locale),
82
+ loader.isPreview(),
83
+ ]);
84
+ return await Promise.all(docs.map((doc) => toCMSContent(doc, options, preview)));
85
+ }
86
+ catch (error) {
87
+ throw loadFailure(error);
88
+ }
89
+ }
90
+ /** Load the live version of every published document in a collection, without bodies: nothing is rendered */
91
+ export async function loadSummaries(collection, locale) {
92
+ const loader = getServerLoader();
93
+ try {
94
+ const [docs, preview] = await Promise.all([
95
+ loader.listPublishedSummaries(collection, locale),
96
+ loader.isPreview(),
97
+ ]);
98
+ return docs.map((doc) => ({
99
+ collection: doc.collection,
100
+ slug: doc.slug,
101
+ locale: doc.locale,
102
+ fields: doc.fields,
103
+ preview,
104
+ }));
105
+ }
106
+ catch (error) {
107
+ throw loadFailure(error);
108
+ }
109
+ }
110
+ //# sourceMappingURL=content-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-loader.js","sourceRoot":"","sources":["../../src/server/content-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { PageStructure } from '@krantho/core';
2
+ /**
3
+ * Resolve the complete JSON-LD graph for a page, composed from its published
4
+ * version: site-level (ProfessionalService, WebSite, Person) + collection-level
5
+ * (Article, Service) + document-level overrides — all in a single @graph, with
6
+ * the page node and what the page's structure states (its trail, its place in
7
+ * a sequence, its kind). Null when the document has no published version, or
8
+ * the loader serves no SEO.
9
+ */
10
+ export declare function resolveJsonLd(collection: string, slug: string, locale?: string | undefined, structure?: PageStructure | undefined): Promise<Record<string, unknown> | null>;
11
+ /**
12
+ * Render the complete JSON-LD structured data for a page.
13
+ *
14
+ * One component, one @graph — contains all entities from the full
15
+ * SEO hierarchy (site → collection → document). Place in each page, and pass
16
+ * the structure the page renders — the trail of its breadcrumb, its place in a
17
+ * sequence, its kind — so the structured data states what the page shows.
18
+ *
19
+ * The layout does NOT render JSON-LD. Each page owns its complete graph.
20
+ */
21
+ export declare function SeoJsonLd({ collection, slug, locale, structure, }: {
22
+ collection: string;
23
+ slug: string;
24
+ locale?: string | undefined;
25
+ structure?: PageStructure | undefined;
26
+ }): Promise<React.ReactElement | null>;
27
+ //# sourceMappingURL=seo-jsonld.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-jsonld.d.ts","sourceRoot":"","sources":["../../src/server/seo-jsonld.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAuBlD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,EAC3B,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAEzC;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,EAC9B,UAAU,EACV,IAAI,EACJ,MAAM,EACN,SAAS,GACV,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,CAAA;CACtC,GAAG,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAWrC"}
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { serializeJsonLd } from '@krantho/seo-shared';
3
+ import { cache } from 'react';
4
+ import { getServerLoader } from './content-loader.js';
5
+ /** One composition per page render; React's cache matches arguments by identity, so the structure travels as JSON */
6
+ const composeJsonLd = cache(async (collection, slug, locale, structure) => {
7
+ const shape = structure ? JSON.parse(structure) : undefined;
8
+ try {
9
+ return (await getServerLoader().jsonLd?.({ collection, slug, locale }, shape)) ?? null;
10
+ }
11
+ catch (error) {
12
+ console.error(`[krantho] JSON-LD for ${collection}/${slug} could not be composed:`, error);
13
+ return null;
14
+ }
15
+ });
16
+ /**
17
+ * Resolve the complete JSON-LD graph for a page, composed from its published
18
+ * version: site-level (ProfessionalService, WebSite, Person) + collection-level
19
+ * (Article, Service) + document-level overrides — all in a single @graph, with
20
+ * the page node and what the page's structure states (its trail, its place in
21
+ * a sequence, its kind). Null when the document has no published version, or
22
+ * the loader serves no SEO.
23
+ */
24
+ export function resolveJsonLd(collection, slug, locale, structure) {
25
+ return composeJsonLd(collection, slug, locale, structure ? JSON.stringify(structure) : undefined);
26
+ }
27
+ /**
28
+ * Render the complete JSON-LD structured data for a page.
29
+ *
30
+ * One component, one @graph — contains all entities from the full
31
+ * SEO hierarchy (site → collection → document). Place in each page, and pass
32
+ * the structure the page renders — the trail of its breadcrumb, its place in a
33
+ * sequence, its kind — so the structured data states what the page shows.
34
+ *
35
+ * The layout does NOT render JSON-LD. Each page owns its complete graph.
36
+ */
37
+ export async function SeoJsonLd({ collection, slug, locale, structure, }) {
38
+ const graph = await resolveJsonLd(collection, slug, locale, structure);
39
+ if (!graph)
40
+ return null;
41
+ return (_jsx("script", { type: "application/ld+json",
42
+ // biome-ignore lint/security/noDangerouslySetInnerHtml: serializeJsonLd escapes `<`, so the JSON cannot end the script tag
43
+ dangerouslySetInnerHTML: { __html: serializeJsonLd(graph) } }));
44
+ }
45
+ //# sourceMappingURL=seo-jsonld.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-jsonld.js","sourceRoot":"","sources":["../../src/server/seo-jsonld.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,qHAAqH;AACrH,MAAM,aAAa,GAAG,KAAK,CACzB,KAAK,EACH,UAAkB,EAClB,IAAY,EACZ,MAA0B,EAC1B,SAA6B,EACY,EAAE;IAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAmB,CAAC,CAAC,CAAC,SAAS,CAAA;IAC9E,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,eAAe,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC,IAAI,IAAI,CAAA;IACxF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,UAAU,IAAI,IAAI,yBAAyB,EAAE,KAAK,CAAC,CAAA;QAC1F,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC,CACF,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,UAAkB,EAClB,IAAY,EACZ,MAA2B,EAC3B,SAAqC;IAErC,OAAO,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AACnG,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAC9B,UAAU,EACV,IAAI,EACJ,MAAM,EACN,SAAS,GAMV;IACC,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA;IACtE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IAEvB,OAAO,CACL,iBACE,IAAI,EAAC,qBAAqB;QAC1B,2HAA2H;QAC3H,uBAAuB,EAAE,EAAE,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,GAC3D,CACH,CAAA;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ /** Resolved SEO metadata for a page */
2
+ export interface SeoMeta {
3
+ title: string;
4
+ description: string;
5
+ image?: string | undefined;
6
+ canonical?: string | undefined;
7
+ author?: string | undefined;
8
+ datePublished?: string | undefined;
9
+ dateModified?: string | undefined;
10
+ og?: {
11
+ title: string;
12
+ description: string;
13
+ image?: string | undefined;
14
+ type: string;
15
+ siteName?: string | undefined;
16
+ url?: string | undefined;
17
+ };
18
+ twitter?: {
19
+ card: string;
20
+ site?: string | undefined;
21
+ };
22
+ }
23
+ /**
24
+ * Resolve SEO metadata for a page.
25
+ *
26
+ * Reads the SEO configuration first (user-edited + AI-generated properties),
27
+ * falls back to CMS content fields, then to site-level OG defaults.
28
+ *
29
+ * Priority: seo_config.properties → CMS fields → site defaults
30
+ */
31
+ export declare const resolveSeoContent: (collection: string, slug: string, locale?: string | undefined) => Promise<SeoMeta>;
32
+ //# sourceMappingURL=seo-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-resolver.d.ts","sourceRoot":"","sources":["../../src/server/seo-resolver.ts"],"names":[],"mappings":"AAiBA,uCAAuC;AACvC,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,EAAE,CAAC,EAAE;QACH,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,EAAE,MAAM,CAAA;QACnB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC1B,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC7B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KACzB,CAAA;IACD,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC1B,CAAA;CACF;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,eACT,MAAM,QAAQ,MAAM,WAAW,MAAM,GAAG,SAAS,KAAG,OAAO,CAAC,OAAO,CAwEvF,CAAA"}
@@ -0,0 +1,84 @@
1
+ import { buildSeoFieldMap, resolveSeoField } from '@krantho/seo-shared';
2
+ import { cache } from 'react';
3
+ import { getServerLoader, loadContent } from './content-loader.js';
4
+ /** The primary entity's properties of an SEO configuration; empty when none or unreadable */
5
+ async function seoConfigProperties(configId, locale) {
6
+ try {
7
+ return (await getServerLoader().seoProperties?.(configId, locale)) ?? {};
8
+ }
9
+ catch (error) {
10
+ console.error(`[krantho] SEO properties for ${configId} could not be read:`, error);
11
+ return {};
12
+ }
13
+ }
14
+ /**
15
+ * Resolve SEO metadata for a page.
16
+ *
17
+ * Reads the SEO configuration first (user-edited + AI-generated properties),
18
+ * falls back to CMS content fields, then to site-level OG defaults.
19
+ *
20
+ * Priority: seo_config.properties → CMS fields → site defaults
21
+ */
22
+ export const resolveSeoContent = cache(async (collection, slug, locale) => {
23
+ // Load CMS content for fallback values
24
+ let cmsFields = {};
25
+ try {
26
+ const content = await loadContent({ collection, slug, locale });
27
+ cmsFields = content.fields;
28
+ }
29
+ catch {
30
+ // Content may not exist yet
31
+ }
32
+ // Load document-level and site-level SEO configs in parallel
33
+ const [seoProps, siteProps] = await Promise.all([
34
+ seoConfigProperties(`doc:${collection}/${slug}`, locale),
35
+ seoConfigProperties('site'),
36
+ ]);
37
+ // Build dynamic field map from CMS fields
38
+ const fieldMap = buildSeoFieldMap(Object.keys(cmsFields));
39
+ // Resolve with priority: seo properties → CMS fields (via field map) → site defaults
40
+ const title = str(seoProps['headline']) ||
41
+ str(seoProps['name']) ||
42
+ resolveSeoField(fieldMap, 'title', cmsFields) ||
43
+ slug;
44
+ const description = str(seoProps['description']) || resolveSeoField(fieldMap, 'description', cmsFields) || '';
45
+ const image = str(seoProps['image']) ||
46
+ resolveSeoField(fieldMap, 'image', cmsFields) ||
47
+ str(siteProps['og-default-image']) ||
48
+ undefined;
49
+ // OG fields: per-document overrides → content fields → resolved values → site defaults
50
+ const ogTitle = resolveSeoField(fieldMap, 'ogTitle', cmsFields) || title;
51
+ const ogDescription = resolveSeoField(fieldMap, 'ogDescription', cmsFields) || description;
52
+ const ogImage = resolveSeoField(fieldMap, 'ogImage', cmsFields) || image;
53
+ const ogType = resolveSeoField(fieldMap, 'ogType', cmsFields) || 'website';
54
+ const siteName = str(siteProps['name']) || undefined;
55
+ const twitterHandle = str(siteProps['twitter-handle']) || undefined;
56
+ const canonicalUrl = str(seoProps['url']) || resolveSeoField(fieldMap, 'canonicalUrl', cmsFields) || undefined;
57
+ return {
58
+ title,
59
+ description,
60
+ image,
61
+ canonical: canonicalUrl,
62
+ author: str(seoProps['author']) || resolveSeoField(fieldMap, 'author', cmsFields) || undefined,
63
+ datePublished: str(seoProps['datePublished']) ||
64
+ resolveSeoField(fieldMap, 'datePublished', cmsFields) ||
65
+ undefined,
66
+ dateModified: str(seoProps['dateModified']) || undefined,
67
+ og: {
68
+ title: ogTitle,
69
+ description: ogDescription,
70
+ image: ogImage,
71
+ type: ogType,
72
+ siteName,
73
+ url: canonicalUrl,
74
+ },
75
+ twitter: {
76
+ card: ogImage ? 'summary_large_image' : 'summary',
77
+ site: twitterHandle,
78
+ },
79
+ };
80
+ });
81
+ function str(v) {
82
+ return typeof v === 'string' && v.length > 0 ? v : '';
83
+ }
84
+ //# sourceMappingURL=seo-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-resolver.js","sourceRoot":"","sources":["../../src/server/seo-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export { NetworkError } from '@krantho/core';
2
+ export { CMSImageServer } from './components/server/CMSImageServer.js';
3
+ export { CMSMarkdownServer } from './components/server/CMSMarkdownServer.js';
4
+ export { CMSTextServer } from './components/server/CMSTextServer.js';
5
+ export { getAllCMSContent, getAllCMSSummaries, getCMSContent, getCMSSlugs, } from './server/cms-context.js';
6
+ export { initServerLoader, loadContent } from './server/content-loader.js';
7
+ export { resolveJsonLd, SeoJsonLd } from './server/seo-jsonld.js';
8
+ export type { SeoMeta } from './server/seo-resolver.js';
9
+ export { resolveSeoContent } from './server/seo-resolver.js';
10
+ export type { CMSContent, CMSContentOptions, CMSImageServerProps, CMSMarkdownServerProps, CMSSummary, CMSSummaryOptions, CMSTextServerProps, ContentLoaderOptions, ContentLocation, } from './types.js';
11
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AAEpE,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,WAAW,GACZ,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACjE,YAAY,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5D,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,GAChB,MAAM,YAAY,CAAA"}
package/dist/server.js ADDED
@@ -0,0 +1,12 @@
1
+ // Server components
2
+ // The error the read path throws — `status` 404 when nothing is published
3
+ export { NetworkError } from '@krantho/core';
4
+ export { CMSImageServer } from './components/server/CMSImageServer.js';
5
+ export { CMSMarkdownServer } from './components/server/CMSMarkdownServer.js';
6
+ export { CMSTextServer } from './components/server/CMSTextServer.js';
7
+ // Server utilities
8
+ export { getAllCMSContent, getAllCMSSummaries, getCMSContent, getCMSSlugs, } from './server/cms-context.js';
9
+ export { initServerLoader, loadContent } from './server/content-loader.js';
10
+ export { resolveJsonLd, SeoJsonLd } from './server/seo-jsonld.js';
11
+ export { resolveSeoContent } from './server/seo-resolver.js';
12
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,oBAAoB;AAEpB,0EAA0E;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAA;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACpE,mBAAmB;AACnB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,WAAW,GACZ,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAEjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,87 @@
1
+ import type { SemanticStyle } from '@krantho/core';
2
+ export declare class ConfigurationError extends Error {
3
+ context?: string | undefined;
4
+ constructor(message: string, context?: string | undefined);
5
+ }
6
+ export interface CMSConfig {
7
+ contentPath?: string;
8
+ assetsPath?: string;
9
+ imagesPath?: string;
10
+ autoReload?: boolean;
11
+ errorBoundary?: boolean;
12
+ cacheContent?: boolean;
13
+ }
14
+ export interface CMSContent {
15
+ collection: string;
16
+ slug: string;
17
+ locale: string;
18
+ fields: Record<string, unknown>;
19
+ html: string;
20
+ rawContent: string;
21
+ sections: Record<string, string>;
22
+ excerpt?: string | undefined;
23
+ /** Whether it was read for an editor's preview: the Live marks apply (`kranthoField`) */
24
+ preview: boolean;
25
+ }
26
+ /** A published document without its body: its fields, for a page that only lists documents */
27
+ export interface CMSSummary {
28
+ collection: string;
29
+ slug: string;
30
+ locale: string;
31
+ fields: Record<string, unknown>;
32
+ /** Whether it was read for an editor's preview: the Live marks apply (`kranthoField`) */
33
+ preview: boolean;
34
+ }
35
+ export interface ContentLoaderOptions {
36
+ processMarkdown?: boolean;
37
+ extractSections?: boolean;
38
+ generateExcerpt?: boolean;
39
+ excerptLength?: number;
40
+ }
41
+ /** Options for listing published summaries in server components */
42
+ export interface CMSSummaryOptions {
43
+ /** Omitted: the site's default locale */
44
+ locale?: string | undefined;
45
+ }
46
+ /** Options for reading published content in server components */
47
+ export interface CMSContentOptions extends ContentLoaderOptions, CMSSummaryOptions {
48
+ }
49
+ /** Which document a server component renders: a slug in a collection, in a locale */
50
+ export interface ContentLocation {
51
+ collection: string;
52
+ /** Omitted: the site's default locale */
53
+ locale?: string | undefined;
54
+ }
55
+ export interface CMSTextProps {
56
+ slug: string;
57
+ field: string;
58
+ variant?: SemanticStyle['variant'];
59
+ color?: SemanticStyle['color'];
60
+ align?: SemanticStyle['align'];
61
+ weight?: SemanticStyle['weight'];
62
+ size?: SemanticStyle['size'];
63
+ fallback?: string;
64
+ className?: string;
65
+ component?: string;
66
+ }
67
+ export interface CMSMarkdownProps {
68
+ slug: string;
69
+ section?: string;
70
+ variant?: SemanticStyle['variant'];
71
+ color?: SemanticStyle['color'];
72
+ align?: SemanticStyle['align'];
73
+ className?: string;
74
+ }
75
+ export type CMSTextServerProps = CMSTextProps & ContentLocation;
76
+ export type CMSMarkdownServerProps = CMSMarkdownProps & ContentLocation;
77
+ export type CMSImageServerProps = CMSImageProps & ContentLocation;
78
+ export interface CMSImageProps {
79
+ slug: string;
80
+ field: string;
81
+ alt?: string;
82
+ width?: number;
83
+ height?: number;
84
+ lazy?: boolean;
85
+ className?: string;
86
+ }
87
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ export class ConfigurationError extends Error {
2
+ context;
3
+ constructor(message, context) {
4
+ super(message);
5
+ this.context = context;
6
+ this.name = 'ConfigurationError';
7
+ }
8
+ }
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAGlC;IAFT,YACE,OAAe,EACR,OAAgB;QAEvB,KAAK,CAAC,OAAO,CAAC,CAAA;QAFP,YAAO,GAAP,OAAO,CAAS;QAGvB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;IAClC,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,48 @@
1
1
  {
2
2
  "name": "@krantho/ui-react",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.0.0",
4
+ "license": "MIT",
5
+ "homepage": "https://krantho.com",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/descoped/krantho.git",
9
+ "directory": "packages/ui-react"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/descoped/krantho/issues"
13
+ },
14
+ "type": "module",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ },
20
+ "./server": {
21
+ "types": "./dist/server.d.ts",
22
+ "import": "./dist/server.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "dependencies": {
29
+ "@krantho/core": "1.0.0",
30
+ "@krantho/seo-shared": "1.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^25.9.9",
34
+ "@types/react": "^19.2.18",
35
+ "@types/react-dom": "^19.2.7",
36
+ "react": "^19.2.9",
37
+ "react-dom": "^19.2.9",
38
+ "typescript": "^6.0.3"
39
+ },
40
+ "peerDependencies": {
41
+ "react": ">=19.0.0"
42
+ },
43
+ "scripts": {
44
+ "build": "tsc",
45
+ "typecheck": "tsc --noEmit",
46
+ "clean": "rm -rf dist"
47
+ }
6
48
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.