@se-studio/contentful-rest-api 1.1.2 → 1.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/CHANGELOG.md +68 -0
- package/README.md +7 -1
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +2 -0
- package/dist/api/context.js.map +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/redirects.d.ts +16 -0
- package/dist/api/redirects.d.ts.map +1 -0
- package/dist/api/redirects.js +106 -0
- package/dist/api/redirects.js.map +1 -0
- package/dist/api/related-articles.d.ts +6 -1
- package/dist/api/related-articles.d.ts.map +1 -1
- package/dist/api/related-articles.js +66 -19
- package/dist/api/related-articles.js.map +1 -1
- package/dist/api/types.d.ts +15 -3
- package/dist/api/types.d.ts.map +1 -1
- package/dist/baseTypes/baseRedirect.d.ts +126 -0
- package/dist/baseTypes/baseRedirect.d.ts.map +1 -0
- package/dist/baseTypes/baseRedirect.js +2 -0
- package/dist/baseTypes/baseRedirect.js.map +1 -0
- package/dist/converters/helpers.d.ts +1 -0
- package/dist/converters/helpers.d.ts.map +1 -1
- package/dist/converters/helpers.js.map +1 -1
- package/dist/converters/index.d.ts +1 -0
- package/dist/converters/index.d.ts.map +1 -1
- package/dist/converters/index.js +1 -0
- package/dist/converters/index.js.map +1 -1
- package/dist/converters/redirect.d.ts +20 -0
- package/dist/converters/redirect.d.ts.map +1 -0
- package/dist/converters/redirect.js +103 -0
- package/dist/converters/redirect.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/revalidation/handlers.d.ts.map +1 -1
- package/dist/revalidation/handlers.js +6 -1
- package/dist/revalidation/handlers.js.map +1 -1
- package/dist/revalidation/tags.d.ts +6 -0
- package/dist/revalidation/tags.d.ts.map +1 -1
- package/dist/revalidation/tags.js +9 -0
- package/dist/revalidation/tags.js.map +1 -1
- package/dist/utils/redirectMap.d.ts +25 -0
- package/dist/utils/redirectMap.d.ts.map +1 -0
- package/dist/utils/redirectMap.js +39 -0
- package/dist/utils/redirectMap.js.map +1 -0
- package/docs/llms.md +9 -3
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,73 @@
|
|
|
1
1
|
# @se-studio/contentful-rest-api
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 31b2200: Add first-class support for managing redirects from Contentful.
|
|
8
|
+
|
|
9
|
+
Editors can now create `redirect` entries (via new content type) using reference pickers for existing Pages/Articles/etc. (for "from" and "to") or raw paths/URLs, plus a status code dropdown (301/302/etc.), active flag, and notes. This makes redirects easy for non-technical users without requiring them to know or type exact slugs.
|
|
10
|
+
|
|
11
|
+
Redirects use the simple rebuild pattern (already proven by A/B tests):
|
|
12
|
+
|
|
13
|
+
- Publish in Contentful → webhook triggers a Vercel Deploy Hook.
|
|
14
|
+
- Build fetches current published redirects (via `getRedirectsWithErrors` / `getRedirectMap` on the helpers from `createAppHelpers`) and bakes a static map (using the new pure `buildRedirectMap`).
|
|
15
|
+
- Middleware performs exact (or lightly normalized) lookups against the baked data with zero runtime cost or external calls.
|
|
16
|
+
|
|
17
|
+
Key additions:
|
|
18
|
+
|
|
19
|
+
- `IRedirect` type + `isRedirect` guard.
|
|
20
|
+
- `BaseRedirectSkeleton`, `baseRedirectConverter` (resolves reference links to concrete `fromPath`/`to` using existing `resolveLink` + project `urlCalculators`).
|
|
21
|
+
- `contentfulRedirectsRest`, revalidation `RedirectTag`, and `buildRedirectMap` / `RedirectMap` types (exported from `@se-studio/contentful-rest-api`).
|
|
22
|
+
- `getRedirectsWithErrors` and `getRedirectMap` (convenience) exposed additively via `createAppHelpers` (like banners).
|
|
23
|
+
- Two Contentful migration scripts: `18-create-redirect-content-type.js` (full CT with rich help text for the picker UX) and `19-remove-redirectTo-fields.js` (cleans up legacy per-page `redirectTo` fields on page/pageVariant).
|
|
24
|
+
- New `@se-studio/skills` entry `se-marketing-sites-redirects` (the canonical guide, including CT spec, migration instructions, generate script example, static middleware example + A/B composition, deploy hook webhook setup, testing, and preview notes).
|
|
25
|
+
- Minimal demo in `example-empty` (middleware + `/api/redirects` route exercising the new helpers at runtime for easy local verification; production apps follow the baked recipe in the skill).
|
|
26
|
+
- Light updates to CLAUDE.md, vercel-setup skill, CONTENT_MODEL.md, and related docs.
|
|
27
|
+
|
|
28
|
+
The model and helpers are forward-compatible if a faster (e.g. Edge Config) path is added later. Legacy `redirectTo` fields are left untouched for now (removal is optional via the migration).
|
|
29
|
+
|
|
30
|
+
This is a new feature (minor bumps).
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Complete support and documentation for filtered full article lists (#51) + fix client boundary regression (#52).
|
|
35
|
+
|
|
36
|
+
- Re-export `filterRelatedArticles` and `RelatedArticlesOptions` **only** from `@se-studio/core-ui/server` (removed from the main barrel). This keeps the primary `@se-studio/core-ui` entry fully client-safe for common imports (`cn`, `TrackedLink`, `AnalyticsProvider`, `Visual`, etc.). The main barrel no longer transitively pulls `'server-only'`.
|
|
37
|
+
|
|
38
|
+
- `getAllArticleLinks(options)` now fully supports the article listing filter fields (`articleTypeSlugs`/`Ids`, `tagSlugs`/`Ids`, `tagType*`, `authorSlugs`/`Ids` + `strictAuthorMatch`, `before`/`after`, `excludeArticleIds`, `count`, `allowUnindexed`) for News Grids, Publications Lists, person-scoped lists, tag filters, etc. The wrapper delegates to the enhanced `filterRelatedArticles` (OR semantics, slug support, strict author mode, distinct tag scoring, etc.).
|
|
39
|
+
|
|
40
|
+
- Added / expanded docs and examples in core-ui and contentful-rest-api READMEs + llms.md, CMS_INFRASTRUCTURE.md, SERVER_CLIENT_BOUNDARIES.md, the `se-marketing-sites-lib-cms-structure` skill (showing the `getAllArticleLinks({ articleTypeSlugs, strictAuthorMatch, ... })` pattern), and this repo's GitHub issues status tracker (new #51 entry + updated upgrade table).
|
|
41
|
+
|
|
42
|
+
- No changes to runtime behavior for existing bare `getAll*Links()` or `getRelated*` callers (sitemaps, search indexing, llms routes, etc. unaffected). Consumers should import filter symbols from the `/server` subpath when using them directly.
|
|
43
|
+
|
|
44
|
+
This finishes the implementation + docs for the DX improvement requested in #51 (reusable core filtering for full article collections instead of per-site `.filter()` shims). The boundary fix prevents the server-only error that appeared in any app importing from core-ui after the initial #51 changes.
|
|
45
|
+
|
|
46
|
+
- Updated dependencies [31b2200]
|
|
47
|
+
- @se-studio/core-data-types@1.2.0
|
|
48
|
+
|
|
49
|
+
## 1.2.0
|
|
50
|
+
|
|
51
|
+
### Minor Changes
|
|
52
|
+
|
|
53
|
+
- feat: support slug-based and tag type filtering for related articles (plus strict author matching)
|
|
54
|
+
|
|
55
|
+
**@se-studio/contentful-rest-api**
|
|
56
|
+
|
|
57
|
+
- Extended `RelatedArticlesOptions` and `filterRelatedArticles` with `articleTypeSlugs`, `tagSlugs`, `tagTypeIds`/`tagTypeSlugs`, `authorSlugs`, and `strictAuthorMatch` (OR semantics with the existing ID-based filters).
|
|
58
|
+
- Tag scoring now correctly counts _distinct_ tags (prevents double-counting when the same tag matches via both an ID and a slug).
|
|
59
|
+
- Updated logging and the `@example` in the JSDoc.
|
|
60
|
+
|
|
61
|
+
**@se-studio/core-ui**
|
|
62
|
+
|
|
63
|
+
- Extended `LinkFetchOptions` (used by `getAll*Links` and `FetchHelpers` / `rendererConfig.fetchHelpers`) with the full set of related article filter fields. Added clear JSDoc noting that the article-specific filters only take effect for `getAllArticleLinks`.
|
|
64
|
+
- `createAppHelpers` now wraps `getAllArticleLinks` so that when any filter criteria (IDs or slugs for types/tags/authors/tagTypes, `strictAuthorMatch`, `excludeArticleIds`, `before`/`after`, `count`) are passed, it fetches the base list then runs it through `filterRelatedArticles` (preserving `errors` and correctly handling `allowUnindexed`).
|
|
65
|
+
- Re-exported `RelatedArticlesOptions` and `filterRelatedArticles` from `@se-studio/core-ui` for convenient use in apps.
|
|
66
|
+
- Added comprehensive tests covering the new filter combinations and the `getAllArticleLinks` wrapper integration.
|
|
67
|
+
- Minor hygiene improvements (import ordering per surgical changes guideline, one-line note that internal `getRelatedArticles`/`getRelatedPeople` now benefit from the richer filter).
|
|
68
|
+
|
|
69
|
+
This enables much more flexible "related content" collections and custom article lists directly from `fetchHelpers.getAllArticleLinks(...)` (or the app helpers) without duplicating filtering/ranking logic.
|
|
70
|
+
|
|
3
71
|
## 1.1.2
|
|
4
72
|
|
|
5
73
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -653,7 +653,13 @@ export async function generateStaticParams() {
|
|
|
653
653
|
- **`contentfulAllPagesRest`** - Fetches all pages from Contentful
|
|
654
654
|
- **`contentfulAllPageLinks`** - Fetches all page links plus **page variant** links (metadata only), deduped by slug (page wins)
|
|
655
655
|
- **`contentfulAllArticleLinks`** - Fetches all article links (lightweight metadata only — no full content). Returns `IContentfulArticleLink[]` (extends `IArticleLink`) including `title`, `subtitle`, `date`, `tags`, `articleType`, `featuredImage` (as `visual`), `visuals`, `description`, optional `download`, and optional `summary` (rich text). Used for listing/browsing UIs. Exposed in apps via `getAllArticleLinks` from `createAppHelpers`.
|
|
656
|
-
- **`filterRelatedArticles`** - Filters and ranks article links
|
|
656
|
+
- **`filterRelatedArticles`** - Filters and ranks article links (used by Related Articles collections *and* full-list helpers). Supports:
|
|
657
|
+
- Article type (ids or `articleTypeSlugs`)
|
|
658
|
+
- Tags (ids or `tagSlugs`; OR match; more matches = higher rank; distinct counting)
|
|
659
|
+
- Tag types (`tagTypeIds` / `tagTypeSlugs`; hard filter)
|
|
660
|
+
- Authors (ids or `authorSlugs`; score boost by default; `strictAuthorMatch: true` turns it into a hard exclude — required for person-scoped News/Pubs lists)
|
|
661
|
+
- Date range (`before` / `after`), `excludeArticleIds`, `count` (undefined = return all), `allowUnindexed`
|
|
662
|
+
Used by `@se-studio/core-ui` `getRelatedArticles` and the `getAllArticleLinks(options)` wrapper. Import from main in server code, or via `@se-studio/core-ui/server`. See `RelatedArticlesOptions` type.
|
|
657
663
|
- **`getBreadcrumbLookup`** - Fetches a map of path → breadcrumb label for resolving breadcrumb segments from URL paths. Uses same caching as sitemap. Use with `resolveBreadcrumbSegments` from `@se-studio/core-ui`.
|
|
658
664
|
|
|
659
665
|
#### Client Functions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,oBAAoB,EAKpB,cAAc,EACf,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,oBAAoB,EAKpB,cAAc,EACf,MAAM,uBAAuB,CAAC;AAc/B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,0BAA0B,CAAC,cAAc,EAAE,cAAc,GAAG,oBAAoB,CAyC/F"}
|
package/dist/api/context.js
CHANGED
|
@@ -9,6 +9,7 @@ import { baseLinkConverter } from '../converters/link';
|
|
|
9
9
|
import { baseNavigationItemConverter } from '../converters/navigationItem';
|
|
10
10
|
import { basePageConverter, basePageLinkConverter, basePageVariantLinkConverter, } from '../converters/page';
|
|
11
11
|
import { basePersonConverter, basePersonLinkConverter } from '../converters/person';
|
|
12
|
+
import { baseRedirectConverter } from '../converters/redirect';
|
|
12
13
|
import { baseTagConverter, baseTagLinkConverter } from '../converters/tag';
|
|
13
14
|
import { baseTagTypeConverter } from '../converters/tagType';
|
|
14
15
|
/**
|
|
@@ -59,6 +60,7 @@ export function createBaseConverterContext(urlCalculators) {
|
|
|
59
60
|
componentResolver: baseComponentConverter,
|
|
60
61
|
collectionResolver: baseCollectionConverter,
|
|
61
62
|
bannerResolver: baseBannerConverter,
|
|
63
|
+
redirectResolver: baseRedirectConverter,
|
|
62
64
|
linkResolver,
|
|
63
65
|
contentResolver,
|
|
64
66
|
urlCalculators,
|
package/dist/api/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AASjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,0BAA0B,CAAC,cAA8B;IACvE,MAAM,YAAY,GAAoB,IAAI,GAAG,EAAE,CAAC;IAChD,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,qBAA6C,CAAC,CAAC;IACxE,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,wBAA8D,CAAC,CAAC;IAC5F,YAAY,CAAC,GAAG,CACd,aAAa,EACb,4BAAsE,CACvE,CAAC;IACF,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,oBAA4C,CAAC,CAAC;IACtE,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,uBAA4D,CAAC,CAAC;IACzF,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,4BAAoD,CAAC,CAAC;IACtF,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAyC,CAAC,CAAC;IACpE,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,2BAAmD,CAAC,CAAC;IAEpF,MAAM,eAAe,GAAuB,IAAI,GAAG,EAAE,CAAC;IACtD,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,uBAAkD,CAAC,CAAC;IACtF,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,sBAAiD,CAAC,CAAC;IACpF,eAAe,CAAC,GAAG,CACjB,mBAAmB,EACnB,8BAAyD,CAC1D,CAAC;IACF,eAAe,CAAC,GAAG,CAAC,eAAe,EAAE,0BAAqD,CAAC,CAAC;IAE5F,OAAO;QACL,YAAY,EAAE,iBAAiB;QAC/B,sBAAsB,EAAE,2BAA2B;QACnD,eAAe,EAAE,oBAAoB;QACrC,mBAAmB,EAAE,wBAAwB;QAC7C,WAAW,EAAE,gBAAgB;QAC7B,eAAe,EAAE,oBAAoB;QACrC,cAAc,EAAE,mBAAmB;QACnC,kBAAkB,EAAE,uBAAuB;QAC3C,iBAAiB,EAAE,sBAAsB;QACzC,kBAAkB,EAAE,uBAAuB;QAC3C,cAAc,EAAE,mBAAmB;QACnC,YAAY;QACZ,eAAe;QACf,cAAc;QACd,WAAW,EAAE,EAAE;KAChB,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/api/context.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AASjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,0BAA0B,CAAC,cAA8B;IACvE,MAAM,YAAY,GAAoB,IAAI,GAAG,EAAE,CAAC;IAChD,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,qBAA6C,CAAC,CAAC;IACxE,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,wBAA8D,CAAC,CAAC;IAC5F,YAAY,CAAC,GAAG,CACd,aAAa,EACb,4BAAsE,CACvE,CAAC;IACF,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,oBAA4C,CAAC,CAAC;IACtE,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,uBAA4D,CAAC,CAAC;IACzF,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,4BAAoD,CAAC,CAAC;IACtF,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAyC,CAAC,CAAC;IACpE,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,2BAAmD,CAAC,CAAC;IAEpF,MAAM,eAAe,GAAuB,IAAI,GAAG,EAAE,CAAC;IACtD,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,uBAAkD,CAAC,CAAC;IACtF,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,sBAAiD,CAAC,CAAC;IACpF,eAAe,CAAC,GAAG,CACjB,mBAAmB,EACnB,8BAAyD,CAC1D,CAAC;IACF,eAAe,CAAC,GAAG,CAAC,eAAe,EAAE,0BAAqD,CAAC,CAAC;IAE5F,OAAO;QACL,YAAY,EAAE,iBAAiB;QAC/B,sBAAsB,EAAE,2BAA2B;QACnD,eAAe,EAAE,oBAAoB;QACrC,mBAAmB,EAAE,wBAAwB;QAC7C,WAAW,EAAE,gBAAgB;QAC7B,eAAe,EAAE,oBAAoB;QACrC,cAAc,EAAE,mBAAmB;QACnC,kBAAkB,EAAE,uBAAuB;QAC3C,iBAAiB,EAAE,sBAAsB;QACzC,kBAAkB,EAAE,uBAAuB;QAC3C,cAAc,EAAE,mBAAmB;QACnC,gBAAgB,EAAE,qBAAqB;QACvC,YAAY;QACZ,eAAe;QACf,cAAc;QACd,WAAW,EAAE,EAAE;KAChB,CAAC;AACJ,CAAC"}
|
package/dist/api/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Provides type-safe functions for fetching content from Contentful
|
|
5
5
|
* with support for caching, retry logic, and error handling.
|
|
6
6
|
*/
|
|
7
|
+
export { buildRedirectMap, type RedirectMap, type RedirectMapEntry } from '../utils/redirectMap';
|
|
7
8
|
export { contentfulArticleRest } from './article';
|
|
8
9
|
export { type ArticleTypeFetchOptions, contentfulArticleTypeRest } from './article-type';
|
|
9
10
|
export { contentfulAssetRest, isBrowserViewable, } from './asset';
|
|
@@ -17,6 +18,7 @@ export { contentfulAllArticleLinks, contentfulAllArticleTypeLinks, contentfulAll
|
|
|
17
18
|
export { contentfulPageRest } from './page';
|
|
18
19
|
export { contentfulPersonRest, type PersonFetchOptions } from './person';
|
|
19
20
|
export { getPreviewEntryInfo, type PreviewContentType, type PreviewEntryInfo } from './preview';
|
|
21
|
+
export { contentfulRedirectsRest } from './redirects';
|
|
20
22
|
export { filterRelatedArticles } from './related-articles';
|
|
21
23
|
export { contentfulArticleSitemapEntries, contentfulArticleTypeSitemapEntries, contentfulPageSitemapEntries, contentfulPersonSitemapEntries, contentfulTagSitemapEntries, createSitemapProvider, getAllSitemapEntries, } from './sitemap';
|
|
22
24
|
export { contentfulTagRest, type TagFetchOptions } from './tag';
|
package/dist/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,KAAK,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AACzF,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,kBAAkB,EACvB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EACL,+BAA+B,EAC/B,mCAAmC,EACnC,4BAA4B,EAC5B,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG3E,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,EACb,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,SAAS,CAAC"}
|
package/dist/api/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Provides type-safe functions for fetching content from Contentful
|
|
5
5
|
* with support for caching, retry logic, and error handling.
|
|
6
6
|
*/
|
|
7
|
+
export { buildRedirectMap } from '../utils/redirectMap';
|
|
7
8
|
// Single entity fetchers
|
|
8
9
|
export { contentfulArticleRest } from './article';
|
|
9
10
|
export { contentfulArticleTypeRest } from './article-type';
|
|
@@ -22,6 +23,7 @@ export { contentfulPageRest } from './page';
|
|
|
22
23
|
export { contentfulPersonRest } from './person';
|
|
23
24
|
// Preview
|
|
24
25
|
export { getPreviewEntryInfo } from './preview';
|
|
26
|
+
export { contentfulRedirectsRest } from './redirects';
|
|
25
27
|
// Related articles
|
|
26
28
|
export { filterRelatedArticles } from './related-articles';
|
|
27
29
|
// Sitemap
|
package/dist/api/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yBAAyB;AACzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAgC,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AACzF,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAGL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,UAAU;AACV,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,wDAAwD;AACxD,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AACnB,qBAAqB;AACrB,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAA2B,MAAM,UAAU,CAAC;AACzE,UAAU;AACV,OAAO,EAAE,mBAAmB,EAAkD,MAAM,WAAW,CAAC;AAChG,mBAAmB;AACnB,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,UAAU;AACV,OAAO,EACL,+BAA+B,EAC/B,mCAAmC,EACnC,4BAA4B,EAC5B,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAwB,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAA4B,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAyB,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAA2C,MAAM,sBAAsB,CAAC;AACjG,yBAAyB;AACzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAgC,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AACzF,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAGL,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,UAAU;AACV,OAAO,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzD,wDAAwD;AACxD,OAAO,EACL,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AACnB,qBAAqB;AACrB,OAAO,EACL,yBAAyB,EACzB,6BAA6B,EAC7B,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAA2B,MAAM,UAAU,CAAC;AACzE,UAAU;AACV,OAAO,EAAE,mBAAmB,EAAkD,MAAM,WAAW,CAAC;AAChG,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,mBAAmB;AACnB,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,UAAU;AACV,OAAO,EACL,+BAA+B,EAC/B,mCAAmC,EACnC,4BAA4B,EAC5B,8BAA8B,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAwB,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAA4B,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAyB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IRedirect } from '@se-studio/core-data-types';
|
|
2
|
+
import type { BaseConverterContext } from '../converters/helpers';
|
|
3
|
+
import type { CmsResponse, ContentfulConfig, FetchOptions } from '../types';
|
|
4
|
+
export { buildRedirectMap, type RedirectMap, type RedirectMapEntry } from '../utils/redirectMap';
|
|
5
|
+
/**
|
|
6
|
+
* Fetches all redirects from Contentful.
|
|
7
|
+
*
|
|
8
|
+
* Returns published redirects (when not in preview). The list is small by design
|
|
9
|
+
* (typically < a few hundred rules) so a full enumeration with pagination is fine.
|
|
10
|
+
*
|
|
11
|
+
* The converter resolves any reference links (fromPage, toArticle, etc.) into
|
|
12
|
+
* concrete fromPath / to strings so callers (build-time bake or future sync)
|
|
13
|
+
* only ever see simple path → target maps.
|
|
14
|
+
*/
|
|
15
|
+
export declare function contentfulRedirectsRest(context: BaseConverterContext, config: ContentfulConfig, options: FetchOptions): Promise<CmsResponse<IRedirect[] | null>>;
|
|
16
|
+
//# sourceMappingURL=redirects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redirects.d.ts","sourceRoot":"","sources":["../../src/api/redirects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAY,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAWtF,OAAO,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEjG;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,oBAAoB,EAC7B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC,CAqG1C"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { getContentfulClient } from '../client';
|
|
2
|
+
import { getCacheTags } from '../revalidation';
|
|
3
|
+
import { withRetry } from '../utils';
|
|
4
|
+
import { convertAllAssets, convertAllIncludes, convertAllRawAssets, } from './helpers';
|
|
5
|
+
// Re-export the pure map builder (implemented in utils so it has zero server-only deps
|
|
6
|
+
// and can be used in build scripts / edge / tests without pulling Next.js server boundaries).
|
|
7
|
+
export { buildRedirectMap } from '../utils/redirectMap';
|
|
8
|
+
/**
|
|
9
|
+
* Fetches all redirects from Contentful.
|
|
10
|
+
*
|
|
11
|
+
* Returns published redirects (when not in preview). The list is small by design
|
|
12
|
+
* (typically < a few hundred rules) so a full enumeration with pagination is fine.
|
|
13
|
+
*
|
|
14
|
+
* The converter resolves any reference links (fromPage, toArticle, etc.) into
|
|
15
|
+
* concrete fromPath / to strings so callers (build-time bake or future sync)
|
|
16
|
+
* only ever see simple path → target maps.
|
|
17
|
+
*/
|
|
18
|
+
export async function contentfulRedirectsRest(context, config, options) {
|
|
19
|
+
const client = getContentfulClient(config, options.preview);
|
|
20
|
+
const redirectCacheTags = getCacheTags('redirect', undefined, options.preview);
|
|
21
|
+
const requestOptions = {
|
|
22
|
+
...options,
|
|
23
|
+
next: {
|
|
24
|
+
...options?.next,
|
|
25
|
+
tags: redirectCacheTags,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
const allRedirects = [];
|
|
29
|
+
const errors = [];
|
|
30
|
+
const pageSize = 100;
|
|
31
|
+
let skip = 0;
|
|
32
|
+
let hasMore = true;
|
|
33
|
+
const fetchFn = async () => {
|
|
34
|
+
while (hasMore) {
|
|
35
|
+
try {
|
|
36
|
+
const redirectResponse = await client.getEntries({
|
|
37
|
+
content_type: 'redirect',
|
|
38
|
+
include: 2, // enough to resolve the link targets we care about for hrefs
|
|
39
|
+
locale: options?.locale,
|
|
40
|
+
limit: pageSize,
|
|
41
|
+
skip,
|
|
42
|
+
}, requestOptions);
|
|
43
|
+
if (!redirectResponse.items.length) {
|
|
44
|
+
hasMore = false;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
const includes = convertAllIncludes(redirectResponse);
|
|
48
|
+
const assets = convertAllAssets(redirectResponse, context);
|
|
49
|
+
const rawAssets = convertAllRawAssets(redirectResponse);
|
|
50
|
+
const fullContext = {
|
|
51
|
+
...context,
|
|
52
|
+
includes,
|
|
53
|
+
assets,
|
|
54
|
+
rawAssets,
|
|
55
|
+
errors: [],
|
|
56
|
+
externalVideoEmbeds: new Map(),
|
|
57
|
+
};
|
|
58
|
+
for (const redirectEntry of redirectResponse.items) {
|
|
59
|
+
if (!redirectEntry.fields)
|
|
60
|
+
continue;
|
|
61
|
+
try {
|
|
62
|
+
const converted = context.redirectResolver(fullContext, redirectEntry);
|
|
63
|
+
allRedirects.push(converted);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
const entryId = redirectEntry.sys.id;
|
|
67
|
+
const entryType = redirectEntry.sys.contentType?.sys?.id;
|
|
68
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown conversion error';
|
|
69
|
+
errors.push({
|
|
70
|
+
entryId,
|
|
71
|
+
entryType,
|
|
72
|
+
message: errorMessage,
|
|
73
|
+
error,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (fullContext.errors.length > 0 &&
|
|
78
|
+
typeof process !== 'undefined' &&
|
|
79
|
+
process.env?.NODE_ENV === 'production') {
|
|
80
|
+
console.error(`CMS conversion errors for redirect:`, {
|
|
81
|
+
errors: fullContext.errors,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
const entryId = 'unknown';
|
|
87
|
+
const entryType = 'redirect';
|
|
88
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown conversion error';
|
|
89
|
+
const cmsError = {
|
|
90
|
+
entryId,
|
|
91
|
+
entryType,
|
|
92
|
+
message: errorMessage,
|
|
93
|
+
error,
|
|
94
|
+
};
|
|
95
|
+
errors.push(cmsError);
|
|
96
|
+
}
|
|
97
|
+
skip += pageSize;
|
|
98
|
+
}
|
|
99
|
+
return { data: allRedirects, errors };
|
|
100
|
+
};
|
|
101
|
+
if (options.retry) {
|
|
102
|
+
return await withRetry(fetchFn, options.retry);
|
|
103
|
+
}
|
|
104
|
+
return await fetchFn();
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=redirects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redirects.js","sourceRoot":"","sources":["../../src/api/redirects.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,12 @@ import type { RelatedArticlesOptions } from './types';
|
|
|
13
13
|
* ```ts
|
|
14
14
|
* const relatedArticles = filterRelatedArticles(allArticles, {
|
|
15
15
|
* articleTypeIds: ['blog-type-id'],
|
|
16
|
-
*
|
|
16
|
+
* articleTypeSlugs: ['resources/news'],
|
|
17
|
+
* tagIds: ['tag-1'],
|
|
18
|
+
* tagSlugs: ['tag-2'],
|
|
19
|
+
* tagTypeSlugs: ['condition'],
|
|
20
|
+
* authorSlugs: ['alice'],
|
|
21
|
+
* strictAuthorMatch: true,
|
|
17
22
|
* excludeArticleIds: [currentArticle.id],
|
|
18
23
|
* count: 3,
|
|
19
24
|
* });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"related-articles.d.ts","sourceRoot":"","sources":["../../src/api/related-articles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD
|
|
1
|
+
{"version":3,"file":"related-articles.d.ts","sourceRoot":"","sources":["../../src/api/related-articles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAClF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,sBAAsB,GAC9B,YAAY,EAAE,CA6JhB"}
|
|
@@ -12,21 +12,31 @@ import { getArticleAuthors } from '@se-studio/core-data-types';
|
|
|
12
12
|
* ```ts
|
|
13
13
|
* const relatedArticles = filterRelatedArticles(allArticles, {
|
|
14
14
|
* articleTypeIds: ['blog-type-id'],
|
|
15
|
-
*
|
|
15
|
+
* articleTypeSlugs: ['resources/news'],
|
|
16
|
+
* tagIds: ['tag-1'],
|
|
17
|
+
* tagSlugs: ['tag-2'],
|
|
18
|
+
* tagTypeSlugs: ['condition'],
|
|
19
|
+
* authorSlugs: ['alice'],
|
|
20
|
+
* strictAuthorMatch: true,
|
|
16
21
|
* excludeArticleIds: [currentArticle.id],
|
|
17
22
|
* count: 3,
|
|
18
23
|
* });
|
|
19
24
|
* ```
|
|
20
25
|
*/
|
|
21
26
|
export function filterRelatedArticles(articles, options) {
|
|
22
|
-
const { excludeArticleIds, articleTypeIds: rawArticleTypeIds, tagIds: rawTagIds, authorIds: rawAuthorIds, before, after, count, } = options;
|
|
23
|
-
// Extract and deduplicate IDs
|
|
27
|
+
const { excludeArticleIds, articleTypeIds: rawArticleTypeIds, articleTypeSlugs: rawArticleTypeSlugs, tagIds: rawTagIds, tagSlugs: rawTagSlugs, tagTypeIds: rawTagTypeIds, tagTypeSlugs: rawTagTypeSlugs, authorIds: rawAuthorIds, authorSlugs: rawAuthorSlugs, strictAuthorMatch, before, after, count, } = options;
|
|
28
|
+
// Extract and deduplicate IDs/slugs
|
|
24
29
|
const excludeIds = excludeArticleIds ? [...new Set(excludeArticleIds)] : [];
|
|
25
30
|
const articleTypeIds = rawArticleTypeIds ? [...new Set(rawArticleTypeIds)] : [];
|
|
31
|
+
const articleTypeSlugs = rawArticleTypeSlugs ? [...new Set(rawArticleTypeSlugs)] : [];
|
|
26
32
|
const tagIds = rawTagIds ? [...new Set(rawTagIds)] : [];
|
|
33
|
+
const tagSlugs = rawTagSlugs ? [...new Set(rawTagSlugs)] : [];
|
|
34
|
+
const tagTypeIds = rawTagTypeIds ? [...new Set(rawTagTypeIds)] : [];
|
|
35
|
+
const tagTypeSlugs = rawTagTypeSlugs ? [...new Set(rawTagTypeSlugs)] : [];
|
|
27
36
|
const authorIds = rawAuthorIds ? [...new Set(rawAuthorIds)] : [];
|
|
37
|
+
const authorSlugs = rawAuthorSlugs ? [...new Set(rawAuthorSlugs)] : [];
|
|
28
38
|
if (process.env.LOG_RELATED_ARTICLES) {
|
|
29
|
-
console.log(`[RelatedArticles:filter] input: ${articles.length} articles, options: articleTypes=${(rawArticleTypeIds ?? []).join(',') || 'none'} tags=${(rawTagIds ?? []).join(',') || 'none'} authors=${(rawAuthorIds ?? []).join(',') || 'none'} count=${count ?? 'all'}`);
|
|
39
|
+
console.log(`[RelatedArticles:filter] input: ${articles.length} articles, options: articleTypes=${[...(rawArticleTypeIds ?? []), ...(rawArticleTypeSlugs ?? [])].join(',') || 'none'} tags=${[...(rawTagIds ?? []), ...(rawTagSlugs ?? [])].join(',') || 'none'} tagTypes=${[...(rawTagTypeIds ?? []), ...(rawTagTypeSlugs ?? [])].join(',') || 'none'} authors=${[...(rawAuthorIds ?? []), ...(rawAuthorSlugs ?? [])].join(',') || 'none'} strictAuthorMatch=${strictAuthorMatch ?? false} count=${count ?? 'all'}`);
|
|
30
40
|
}
|
|
31
41
|
// Score and filter articles
|
|
32
42
|
const scoredArticles = articles
|
|
@@ -40,9 +50,15 @@ export function filterRelatedArticles(articles, options) {
|
|
|
40
50
|
if (excludeIds.length > 0 && excludeIds.includes(article.id)) {
|
|
41
51
|
return null;
|
|
42
52
|
}
|
|
43
|
-
// Filter: Article type (match any of the provided types)
|
|
44
|
-
if (articleTypeIds.length > 0) {
|
|
45
|
-
|
|
53
|
+
// Filter: Article type (match any of the provided types by ID or slug)
|
|
54
|
+
if (articleTypeIds.length > 0 || articleTypeSlugs.length > 0) {
|
|
55
|
+
const matchesById = articleTypeIds.length > 0 &&
|
|
56
|
+
!!article.articleType?.id &&
|
|
57
|
+
articleTypeIds.includes(article.articleType.id);
|
|
58
|
+
const matchesBySlug = articleTypeSlugs.length > 0 &&
|
|
59
|
+
!!article.articleType?.slug &&
|
|
60
|
+
articleTypeSlugs.includes(article.articleType.slug);
|
|
61
|
+
if (!matchesById && !matchesBySlug) {
|
|
46
62
|
return null;
|
|
47
63
|
}
|
|
48
64
|
}
|
|
@@ -56,21 +72,52 @@ export function filterRelatedArticles(articles, options) {
|
|
|
56
72
|
return null;
|
|
57
73
|
}
|
|
58
74
|
}
|
|
59
|
-
// Filter + score: Tag matching (must match at least one; more matches = higher score)
|
|
60
|
-
if (tagIds.length > 0) {
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
if (
|
|
75
|
+
// Filter + score: Tag matching by ID or slug (must match at least one; more matches = higher score)
|
|
76
|
+
if (tagIds.length > 0 || tagSlugs.length > 0) {
|
|
77
|
+
const articleTags = article.tags ?? [];
|
|
78
|
+
const matchingTagIds = new Set();
|
|
79
|
+
if (tagIds.length > 0) {
|
|
80
|
+
for (const id of tagIds) {
|
|
81
|
+
const tag = articleTags.find((t) => t.id === id);
|
|
82
|
+
if (tag?.id)
|
|
83
|
+
matchingTagIds.add(tag.id);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (tagSlugs.length > 0) {
|
|
87
|
+
for (const slug of tagSlugs) {
|
|
88
|
+
const tag = articleTags.find((t) => t.slug === slug);
|
|
89
|
+
if (tag?.id)
|
|
90
|
+
matchingTagIds.add(tag.id);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const totalMatches = matchingTagIds.size;
|
|
94
|
+
if (totalMatches === 0) {
|
|
64
95
|
return null;
|
|
65
96
|
}
|
|
66
|
-
score +=
|
|
97
|
+
score += totalMatches * 10; // Each matching *distinct* tag adds 10 points
|
|
67
98
|
}
|
|
68
|
-
//
|
|
69
|
-
if (
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
.
|
|
73
|
-
|
|
99
|
+
// Filter: Tag type matching (hard filter — no scoring)
|
|
100
|
+
if (tagTypeIds.length > 0 || tagTypeSlugs.length > 0) {
|
|
101
|
+
const articleTags = article.tags ?? [];
|
|
102
|
+
const matchesById = tagTypeIds.length > 0 &&
|
|
103
|
+
articleTags.some((t) => t.tagType?.id && tagTypeIds.includes(t.tagType.id));
|
|
104
|
+
const matchesBySlug = tagTypeSlugs.length > 0 &&
|
|
105
|
+
articleTags.some((t) => t.tagType?.slug && tagTypeSlugs.includes(t.tagType.slug));
|
|
106
|
+
if (!matchesById && !matchesBySlug) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Filter/score: Author matching by ID or slug
|
|
111
|
+
if (authorIds.length > 0 || authorSlugs.length > 0) {
|
|
112
|
+
const articleAuthors = getArticleAuthors(article);
|
|
113
|
+
const matchesById = authorIds.length > 0 && articleAuthors.some((p) => p.id && authorIds.includes(p.id));
|
|
114
|
+
const matchesBySlug = authorSlugs.length > 0 &&
|
|
115
|
+
articleAuthors.some((p) => p.slug && authorSlugs.includes(p.slug));
|
|
116
|
+
const hasMatch = matchesById || matchesBySlug;
|
|
117
|
+
if (strictAuthorMatch && !hasMatch) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
if (hasMatch) {
|
|
74
121
|
score += 5; // Matching author adds 5 points
|
|
75
122
|
}
|
|
76
123
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"related-articles.js","sourceRoot":"","sources":["../../src/api/related-articles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAqB,MAAM,4BAA4B,CAAC;AAGlF
|
|
1
|
+
{"version":3,"file":"related-articles.js","sourceRoot":"","sources":["../../src/api/related-articles.ts"],"names":[],"mappings":"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"}
|
package/dist/api/types.d.ts
CHANGED
|
@@ -56,12 +56,24 @@ export interface SitemapConfig {
|
|
|
56
56
|
export interface RelatedArticlesOptions {
|
|
57
57
|
/** Articles to exclude from results */
|
|
58
58
|
excludeArticleIds?: string[];
|
|
59
|
-
/** Filter to articles matching any of these article
|
|
59
|
+
/** Filter to articles matching any of these article type IDs (OR) */
|
|
60
60
|
articleTypeIds?: string[];
|
|
61
|
-
/** Filter to articles matching any of these
|
|
61
|
+
/** Filter to articles matching any of these article type slugs (OR) */
|
|
62
|
+
articleTypeSlugs?: string[];
|
|
63
|
+
/** Filter to articles matching any of these tag IDs (OR); articles with more matches rank higher */
|
|
62
64
|
tagIds?: string[];
|
|
63
|
-
/** Filter
|
|
65
|
+
/** Filter to articles matching any of these tag slugs (OR); articles with more matches rank higher */
|
|
66
|
+
tagSlugs?: string[];
|
|
67
|
+
/** Filter to articles that have at least one tag belonging to any of these tag type IDs */
|
|
68
|
+
tagTypeIds?: string[];
|
|
69
|
+
/** Filter to articles that have at least one tag belonging to any of these tag type slugs */
|
|
70
|
+
tagTypeSlugs?: string[];
|
|
71
|
+
/** Filter/rank by author IDs - articles with matching authors are ranked higher */
|
|
64
72
|
authorIds?: string[];
|
|
73
|
+
/** Filter/rank by author slugs - articles with matching authors are ranked higher */
|
|
74
|
+
authorSlugs?: string[];
|
|
75
|
+
/** When true, authorIds/authorSlugs become a hard filter (exclude non-matching) rather than just a ranking boost */
|
|
76
|
+
strictAuthorMatch?: boolean;
|
|
65
77
|
/** Only include articles published before this date */
|
|
66
78
|
before?: Date;
|
|
67
79
|
/** Only include articles published after this date */
|
package/dist/api/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,QAAQ,EACR,aAAa,EACb,WAAW,EACX,eAAe,EAChB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE5E,MAAM,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAE7D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CAC7C;AAMD;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAC9B,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,CAAC;AAEZ;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,uDAAuD;IACvD,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,yCAAyC;IACzC,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,eAAe,CAAC,EAAE,sBAAsB,CAAC;CAC1C;AAED;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,CACjC,OAAO,EAAE,oBAAoB,EAC7B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,SAAS,EAAE,oBAAoB,EAAE,CAAC;CACnC;AAMD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
|