@se-studio/core-ui 1.12.4 → 1.13.1

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # @se-studio/core-ui
2
2
 
3
+ ## 1.13.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Move `buildListingItems`, `buildListingStructuredDataContext`, and related types from the main barrel to `@se-studio/core-ui/server`. Mark `listingStructuredData` with `server-only` so client imports of `cn`, `Visual`, etc. no longer transitively load `@se-studio/contentful-rest-api` (fixes Next.js `server-only` / Turbopack errors when `'use client'` modules import from the main entry).
8
+
9
+ Add `PACKAGE_EXPORT_BOUNDARIES.md`, a main-barrel regression test, and documentation updates for maintainers and consumer workarounds.
10
+
11
+ ## 1.13.0
12
+
13
+ ### Minor Changes
14
+
15
+ - Add Schema.org markup generators (BreadcrumbList, Blog, ItemList, Product, Service, etc.), fix BlogPosting Mustache variables and Organization type, and add ItemList listing context helpers for structured data templates.
16
+
3
17
  ## 1.12.4
4
18
 
5
19
  ### Patch Changes
package/README.md CHANGED
@@ -420,6 +420,7 @@ const previewConfig = mergeCmsRendererConfig(
420
420
  - **`createAppHelpers`** — Factory for `getAll*Links`, `getPageWithErrors`, `getRelatedArticles`, `getSitemapEntries` (when configured), etc. Wire with your converterContext + buildOptions.
421
421
  - **`filterRelatedArticles`** + **`RelatedArticlesOptions`** — Re-export of the pure article list filter/ranker (articleType/tag/author/tagType slugs+ids, strict author mode, scoring, dates, etc.). Use in collection renderers or custom full-list logic (e.g. News Grids, person-scoped Publications lists). `getAllArticleLinks(options)` on the helpers already applies these filters when you pass `articleTypeSlugs`, `strictAuthorMatch`, etc.
422
422
  - **`getRelatedArticles`** / **`getRelatedPeople`** / **`getRelatedTags`** (also re-exported here for server collections)
423
+ - **`buildListingItems`** / **`buildListingStructuredDataContext`** — ItemList JSON-LD context for article-type, tag, and person listing pages (async CMS fetch via `getAllArticleLinks` + `filterRelatedArticles`)
423
424
 
424
425
  #### Sitemap Utilities
425
426
  - **`buildSitemap`** - Builds a Next.js sitemap from multiple async sources; calls each source in parallel, deduplicates by URL, and converts to `MetadataRoute.Sitemap`
@@ -4,6 +4,8 @@ export { filterRelatedArticles } from '@se-studio/contentful-rest-api';
4
4
  export type { AppHelpers, AppHelpersConfig, AppHelpersWithSitemap, } from '../app-helpers';
5
5
  export { createAppHelpers } from '../app-helpers';
6
6
  export { getRelatedArticles, getRelatedPeople, getRelatedTags, } from '../utils/componentUtils';
7
+ export type { BuildListingItemsOptions, ListingFetchHelpers, ListingStructuredDataItem, } from '../utils/listingStructuredData';
8
+ export { buildListingItems, buildListingStructuredDataContext, } from '../utils/listingStructuredData';
7
9
  export type { RouteHandlersConfig } from './route-handlers';
8
10
  export { createRouteHandlers } from './route-handlers';
9
11
  export type { CmsPagePreparationResult, PrepareArticlePageInput, PrepareArticleTypePageInput, PrepareArticleTypesIndexPageInput, PrepareArticleTypeTagPageInput, PrepareCustomTypePageInput, PreparePageInput, PreparePersonPageInput, PrepareTagPageInput, PrepareTagsIndexPageInput, PrepareTeamIndexPageInput, RouteHandlersPrepareHooks, } from './route-handlers-types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EACV,wBAAwB,EACxB,uBAAuB,EACvB,2BAA2B,EAC3B,iCAAiC,EACjC,8BAA8B,EAC9B,0BAA0B,EAC1B,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,wBAAwB,EACxB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,iBAAiB,EACjB,iCAAiC,GAClC,MAAM,gCAAgC,CAAC;AACxC,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EACV,wBAAwB,EACxB,uBAAuB,EACvB,2BAA2B,EAC3B,iCAAiC,EACjC,8BAA8B,EAC9B,0BAA0B,EAC1B,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -2,6 +2,7 @@ import 'server-only';
2
2
  export { filterRelatedArticles } from '@se-studio/contentful-rest-api';
3
3
  export { createAppHelpers } from '../app-helpers';
4
4
  export { getRelatedArticles, getRelatedPeople, getRelatedTags, } from '../utils/componentUtils';
5
+ export { buildListingItems, buildListingStructuredDataContext, } from '../utils/listingStructuredData';
5
6
  export { createRouteHandlers } from './route-handlers';
6
7
  export { toBreadcrumbOptions } from './route-types';
7
8
  export { canRenderArticleTypeTagRoute, canRenderTagIndex } from './tag-index-guards';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAMvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAuBvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAGrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAMvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,MAAM,yBAAyB,CAAC;AAMjC,OAAO,EACL,iBAAiB,EACjB,iCAAiC,GAClC,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAuBvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,28 @@
1
+ import 'server-only';
2
+ import type { IBaseModel } from '@se-studio/core-data-types';
3
+ import type { FetchHelpers } from '../CmsRendererConfig';
4
+ import type { IBuildInformation } from './buildPageMetadata';
5
+ import { type BuildStructuredDataContextOptions, type StructuredDataContext } from './structuredDataUtils';
6
+ /** One entry in an ItemList JSON-LD template (`listing.items`). */
7
+ export interface ListingStructuredDataItem {
8
+ position: number;
9
+ name: string;
10
+ url: string;
11
+ /** When false, Mustache templates emit a trailing comma between ListItems. */
12
+ last: boolean;
13
+ }
14
+ export interface BuildListingItemsOptions {
15
+ /** Maximum items in the list. Default 12. */
16
+ maxItems?: number;
17
+ }
18
+ export type ListingFetchHelpers = Pick<FetchHelpers, 'getAllArticleLinks'>;
19
+ /**
20
+ * Resolves ItemList entries for article type index, tag, and person profile pages.
21
+ * Returns an empty array when the model type is unsupported or fetch helpers are missing.
22
+ */
23
+ export declare function buildListingItems(model: IBaseModel, baseUrl: string, helpers: ListingFetchHelpers, options?: BuildListingItemsOptions): Promise<ListingStructuredDataItem[]>;
24
+ /**
25
+ * Builds structured data context with optional `listing.items` for ItemList Mustache templates.
26
+ */
27
+ export declare function buildListingStructuredDataContext(model: IBaseModel, config: IBuildInformation, helpers: ListingFetchHelpers, extraOptions?: BuildStructuredDataContextOptions, listingOptions?: BuildListingItemsOptions): Promise<StructuredDataContext>;
28
+ //# sourceMappingURL=listingStructuredData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listingStructuredData.d.ts","sourceRoot":"","sources":["../../src/utils/listingStructuredData.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAgB,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACL,KAAK,iCAAiC,EAEtC,KAAK,qBAAqB,EAC3B,MAAM,uBAAuB,CAAC;AAE/B,mEAAmE;AACnE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,8EAA8E;IAC9E,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;AAoB3E;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,EAC5B,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAkCtC;AAED;;GAEG;AACH,wBAAsB,iCAAiC,CACrD,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,mBAAmB,EAC5B,YAAY,CAAC,EAAE,iCAAiC,EAChD,cAAc,CAAC,EAAE,wBAAwB,GACxC,OAAO,CAAC,qBAAqB,CAAC,CAOhC"}
@@ -0,0 +1,65 @@
1
+ import 'server-only';
2
+ import { filterRelatedArticles } from '@se-studio/contentful-rest-api';
3
+ import { buildStructuredDataContext, } from './structuredDataUtils';
4
+ const DEFAULT_MAX_ITEMS = 12;
5
+ function articleLinksToListingItems(articles, baseUrl) {
6
+ const items = articles.map((article, index) => {
7
+ const href = article.href.startsWith('http') ? article.href : `${baseUrl}${article.href}`;
8
+ return {
9
+ position: index + 1,
10
+ name: article.title ?? article.name,
11
+ url: href,
12
+ last: index === articles.length - 1,
13
+ };
14
+ });
15
+ return items;
16
+ }
17
+ /**
18
+ * Resolves ItemList entries for article type index, tag, and person profile pages.
19
+ * Returns an empty array when the model type is unsupported or fetch helpers are missing.
20
+ */
21
+ export async function buildListingItems(model, baseUrl, helpers, options) {
22
+ const getAllArticleLinks = helpers.getAllArticleLinks;
23
+ if (!getAllArticleLinks) {
24
+ return [];
25
+ }
26
+ const maxItems = options?.maxItems ?? DEFAULT_MAX_ITEMS;
27
+ const response = await getAllArticleLinks({ fetchProfile: 'listing' });
28
+ const articles = response.data ?? [];
29
+ if (articles.length === 0) {
30
+ return [];
31
+ }
32
+ let filtered = [];
33
+ if (model.type === 'Article type') {
34
+ filtered = filterRelatedArticles(articles, {
35
+ articleTypeSlugs: [model.slug],
36
+ count: maxItems,
37
+ });
38
+ }
39
+ else if (model.type === 'Tag') {
40
+ filtered = filterRelatedArticles(articles, {
41
+ tagSlugs: [model.slug],
42
+ count: maxItems,
43
+ });
44
+ }
45
+ else if (model.type === 'Person') {
46
+ filtered = filterRelatedArticles(articles, {
47
+ authorSlugs: [model.slug],
48
+ strictAuthorMatch: true,
49
+ count: maxItems,
50
+ });
51
+ }
52
+ return articleLinksToListingItems(filtered, baseUrl);
53
+ }
54
+ /**
55
+ * Builds structured data context with optional `listing.items` for ItemList Mustache templates.
56
+ */
57
+ export async function buildListingStructuredDataContext(model, config, helpers, extraOptions, listingOptions) {
58
+ const items = await buildListingItems(model, config.baseUrl, helpers, listingOptions);
59
+ const listing = items.length > 0 ? { items } : undefined;
60
+ return buildStructuredDataContext(model, config, {
61
+ ...extraOptions,
62
+ ...(listing ? { listing } : {}),
63
+ });
64
+ }
65
+ //# sourceMappingURL=listingStructuredData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listingStructuredData.js","sourceRoot":"","sources":["../../src/utils/listingStructuredData.ts"],"names":[],"mappings":"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"}
@@ -58,6 +58,7 @@ import type { IBuildInformation } from './buildPageMetadata';
58
58
  * {{#url}}"item": {"@id": "{{{url}}}"}{{/url}}) so non-link segments get only name and position.
59
59
  * - `article.*` - Article-specific fields (only for Article pages)
60
60
  * - `person.*` - Person-specific fields (only for Person pages)
61
+ * - `listing.items` - ItemList entries (position, name, url, last) when provided
61
62
  *
62
63
  * @see {@link StructuredDataContext} for complete context interface
63
64
  */
@@ -105,6 +106,15 @@ export interface StructuredDataContext {
105
106
  jobTitle?: string;
106
107
  imageUrl?: string;
107
108
  };
109
+ /** ItemList context for hub/index pages (article type, tag, person). */
110
+ listing?: {
111
+ items: Array<{
112
+ position: number;
113
+ name: string;
114
+ url: string;
115
+ last: boolean;
116
+ }>;
117
+ };
108
118
  [key: string]: unknown;
109
119
  }
110
120
  /**
@@ -125,6 +135,8 @@ export declare function buildMergedStructuredDataJson(parsedSchemas: unknown[]):
125
135
  export interface BuildStructuredDataContextOptions {
126
136
  /** Pre-resolved breadcrumb segments from resolveBreadcrumbSegments. When provided, used for Schema.org instead of slug-derived labels. */
127
137
  resolvedBreadcrumbs?: BreadcrumbSegment[] | null;
138
+ /** Pre-built ItemList entries for hub/index pages. */
139
+ listing?: StructuredDataContext['listing'];
128
140
  [key: string]: unknown;
129
141
  }
130
142
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"structuredDataUtils.d.ts","sourceRoot":"","sources":["../../src/utils/structuredDataUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EAEhB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAqB;IAEpC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IAGnB,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KACrF,CAAC;IAGF,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,uDAAuD;QACvD,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IAGF,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IAGF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAUD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,EAAE,CAY5D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,OAAO,EAAE,GAAG,OAAO,CAkB/E;AAyGD;;GAEG;AACH,MAAM,WAAW,iCAAiC;IAChD,0IAA0I;IAC1I,mBAAmB,CAAC,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC;IACjD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,iBAAiB,EACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iCAAiC,GAClF,qBAAqB,CAiFvB"}
1
+ {"version":3,"file":"structuredDataUtils.d.ts","sourceRoot":"","sources":["../../src/utils/structuredDataUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,UAAU,EAEhB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAqB;IAEpC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IAGnB,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KACrF,CAAC;IAGF,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,uDAAuD;QACvD,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IAGF,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF,wEAAwE;IACxE,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;KAC9E,CAAC;IAGF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAUD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,EAAE,CAY5D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,aAAa,EAAE,OAAO,EAAE,GAAG,OAAO,CAkB/E;AAyGD;;GAEG;AACH,MAAM,WAAW,iCAAiC;IAChD,0IAA0I;IAC1I,mBAAmB,CAAC,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC;IACjD,sDAAsD;IACtD,OAAO,CAAC,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,iBAAiB,EACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iCAAiC,GAClF,qBAAqB,CAmFvB"}
@@ -152,6 +152,7 @@ export function buildStructuredDataContext(model, config, extraContextOrOptions)
152
152
  const resolvedBreadcrumbs = opts?.resolvedBreadcrumbs;
153
153
  const extraContext = { ...opts };
154
154
  delete extraContext.resolvedBreadcrumbs;
155
+ delete extraContext.listing;
155
156
  const breadcrumbs = resolvedBreadcrumbs && resolvedBreadcrumbs.length > 0
156
157
  ? segmentsToStructuredData(resolvedBreadcrumbs, baseUrl, path)
157
158
  : buildBreadcrumbs(path, baseUrl, model.title, model.breadcrumbTitle);
@@ -166,6 +167,7 @@ export function buildStructuredDataContext(model, config, extraContextOrOptions)
166
167
  imageUrl,
167
168
  breadcrumbs,
168
169
  },
170
+ ...(opts?.listing ? { listing: opts.listing } : {}),
169
171
  ...extraContext,
170
172
  };
171
173
  // Article-specific context
@@ -1 +1 @@
1
- {"version":3,"file":"structuredDataUtils.js","sourceRoot":"","sources":["../../src/utils/structuredDataUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"structuredDataUtils.js","sourceRoot":"","sources":["../../src/utils/structuredDataUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ # `@se-studio/core-ui` — package export boundaries
2
+
3
+ This doc is for **core-ui maintainers** and **consumer-site developers**. It explains which entry point to use, how to avoid leaking server CMS code into client bundles, and what to do when Next.js reports `server-only` / `contentful-rest-api` errors.
4
+
5
+ See also: monorepo [`docs/SERVER_CLIENT_BOUNDARIES.md`](../../../docs/SERVER_CLIENT_BOUNDARIES.md) (app-level `cms-server` rules).
6
+
7
+ ## Mental model (SSR is not “server-only”)
8
+
9
+ Next.js App Router mixes **Server Components** and **Client Components** (`'use client'`) in one module graph. Anything reachable from a client file must be **client-bundle safe**.
10
+
11
+ | Entry | Who may import | Contents |
12
+ |-------|----------------|----------|
13
+ | `@se-studio/core-ui` | **Everyone** — `'use client'` files, server components, registrations | React UI, hooks, `cn`, CMS renderers, registration helpers, shared types |
14
+ | `@se-studio/core-ui/server` | **Server only** — `import 'server-only'` at top | `createAppHelpers`, `createRouteHandlers`, `getRelated*`, `filterRelatedArticles`, listing structured-data helpers, etc. |
15
+ | `@se-studio/core-ui/route-handlers` | **App route modules** (Node `fs`) | Discovery/guidelines/cms.txt handlers |
16
+
17
+ **Do not add a `/client` entry** unless you want stricter enforcement. The main barrel *is* the client-safe surface; `/server` is the explicit server escape hatch.
18
+
19
+ ## Rules for maintainers (adding exports to core-ui)
20
+
21
+ Before exporting a new symbol from `src/index.ts`:
22
+
23
+ 1. **No runtime imports** of `@se-studio/contentful-rest-api` in the main-barrel graph. Type-only imports (`import type`) are OK.
24
+ 2. **No `import 'server-only'`** modules re-exported with runtime bindings from `src/index.ts`. Types-only re-exports from server modules are OK (e.g. `export type { AppHelpers } from './app-helpers'`).
25
+ 3. **Async CMS fetch helpers** (`getAll*Links`, `filterRelatedArticles`, structured-data builders) belong on **`src/server/index.ts`**, with `import 'server-only'` in the implementing file.
26
+ 4. **Pure utilities** (`cn`, breadcrumbs, metadata builders without CMS fetch) stay on the main barrel.
27
+ 5. **Dev-only surfaces** (showcase mocks) should eventually move to `@se-studio/core-ui/showcase` so production apps do not pull them through the main barrel.
28
+
29
+ ### Checklist when opening a core-ui PR
30
+
31
+ - [ ] New CMS / Contentful / Node API code is behind `/server` or `/route-handlers`, not `src/index.ts`.
32
+ - [ ] New server modules include `import 'server-only'` at the top.
33
+ - [ ] `pnpm --filter @se-studio/core-ui test` passes (includes `main-barrel-boundary.test.ts`).
34
+ - [ ] `docs/llms.md` and `README.md` list new server exports under “Server-only exports”.
35
+ - [ ] Consumer apps import new server helpers from `@se-studio/core-ui/server`, not the main entry.
36
+
37
+ ## Rules for consumer sites
38
+
39
+ ### Safe (main entry)
40
+
41
+ ```ts
42
+ import { cn, Visual, CmsContent, getPreviewFieldProps } from '@se-studio/core-ui';
43
+ ```
44
+
45
+ Use in server components **and** `'use client'` files.
46
+
47
+ ### Server only (`/server`)
48
+
49
+ ```ts
50
+ import {
51
+ createAppHelpers,
52
+ buildListingStructuredDataContext,
53
+ filterRelatedArticles,
54
+ } from '@se-studio/core-ui/server';
55
+ ```
56
+
57
+ Use only in server modules (`import 'server-only'` app files, route handlers, `generateMetadata`, etc.). **Never** in `'use client'` files or files imported by registrations that client components transitively load.
58
+
59
+ ### App `cms-server`
60
+
61
+ Each marketing site’s `src/lib/cms-server.ts` must keep `import 'server-only'`. Client components must not import it. See `docs/SERVER_CLIENT_BOUNDARIES.md`.
62
+
63
+ ## How mistakes surface
64
+
65
+ Typical Next.js / Turbopack error:
66
+
67
+ ```
68
+ 'server-only' cannot be imported from a Client Component module.
69
+ The error was caused by importing '@se-studio/contentful-rest-api/dist/converters'
70
+ ```
71
+
72
+ Import trace often shows:
73
+
74
+ - `'use client'` file → `@se-studio/core-ui` (main barrel) → server CMS module → `contentful-rest-api`
75
+
76
+ **Root cause:** a server CMS helper was exported from the main barrel, or a client file imports `/server` / `cms-server`.
77
+
78
+ ## Workarounds (consumer sites, until package is fixed)
79
+
80
+ Prefer fixing and publishing core-ui. If blocked on an older version:
81
+
82
+ | Workaround | Use when | Caveats |
83
+ |------------|----------|---------|
84
+ | Import server helpers from `@se-studio/core-ui/server` | You added a server util on the wrong entry in an older core-ui | Requires that symbol to exist on `/server` in your installed version |
85
+ | Local `cn` via `clsx` + `tailwind-merge` | Build fails on `EmailInputForm` / UI importing `cn` from main barrel | Forks a one-liner utility; remove after package fix |
86
+ | `experimental.optimizePackageImports: ['@se-studio/core-ui']` in `next.config` | Turbopack pulls whole barrel for named imports | **Experimental**; Next docs say not recommended for production; behavior differs Webpack vs Turbopack |
87
+ | `pnpm pack` + install local tarball | Verify fix before npm publish | See `scripts/pack-local-packages-for-consumer.sh` |
88
+
89
+ **Do not** duplicate `ExternalVideoPlayButtonProvider` locally — core-ui video embeds read the package’s own React context module; a local copy breaks custom play buttons.
90
+
91
+ ## Regression test
92
+
93
+ `packages/core-ui/src/__tests__/main-barrel-boundary.test.ts` asserts the main barrel does not re-export known server CMS modules. Extend it when moving additional exports to `/server`.
94
+
95
+ ## Related incidents
96
+
97
+ - **filterRelatedArticles** removed from main barrel (core-ui ~1.11) — same class of bug.
98
+ - **listingStructuredData** moved to `/server` (core-ui 1.13.1) — `buildListingItems` / `buildListingStructuredDataContext` had runtime `contentful-rest-api` import on main entry.
package/docs/llms.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Shared React component library for SE Studio Next.js apps. Provides the CMS rendering system, media components, analytics, and utility hooks.
4
4
 
5
- > **Critical:** This package has a server/client boundary. `@se-studio/core-ui/server` is server-only. Never import server exports in `'use client'` files. Never import from `cms-server` inside component/collection registrations (circular dependency). See the server import rules below.
5
+ > **Critical:** This package has a server/client boundary. `@se-studio/core-ui/server` is server-only. Never import server exports in `'use client'` files. Never import from `cms-server` inside component/collection registrations (circular dependency). The **main** entry must stay client-safe — do not add runtime `@se-studio/contentful-rest-api` imports to `src/index.ts`. See `docs/PACKAGE_EXPORT_BOUNDARIES.md` and the server import rules below.
6
6
 
7
7
  ## CMS Rendering System
8
8
 
@@ -58,8 +58,7 @@ export const myCollection = defineCollection({
58
58
  Use this to pick the correct heading element per component index on the page:
59
59
 
60
60
  ```tsx
61
- import { getSizingInformation } from '@se-studio/core-ui/server'; // server-only
62
- // OR from the app's cms-server
61
+ // From the app's SizingInformation module (per-project), not core-ui/server
63
62
 
64
63
  // In a component renderer:
65
64
  const { Element, ChildElement } = getSizingInformation(index);
@@ -209,7 +208,10 @@ These are server-only — do NOT import in `'use client'` files or component reg
209
208
  import { createRouteHandlers } from '@se-studio/core-ui/server';
210
209
  import { getRelatedArticles, getRelatedPeople, getRelatedTags } from '@se-studio/core-ui/server';
211
210
  import { filterRelatedArticles, type RelatedArticlesOptions } from '@se-studio/core-ui/server';
212
- import { getSizingInformation } from '@se-studio/core-ui/server';
211
+ import {
212
+ buildListingItems,
213
+ buildListingStructuredDataContext,
214
+ } from '@se-studio/core-ui/server';
213
215
  import type { CmsRouteConfig } from '@se-studio/core-ui/server';
214
216
  ```
215
217
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@se-studio/core-ui",
3
- "version": "1.12.4",
3
+ "version": "1.13.1",
4
4
  "description": "Shared React UI component library with Tailwind CSS v4 for SE Studio applications",
5
5
  "repository": {
6
6
  "type": "git",