@se-studio/contentful-rest-api 0.0.0-next16-20260822103555
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 +2036 -0
- package/README.md +764 -0
- package/dist/api/article-type.d.ts +37 -0
- package/dist/api/article-type.d.ts.map +1 -0
- package/dist/api/article-type.js +140 -0
- package/dist/api/article-type.js.map +1 -0
- package/dist/api/article.d.ts +32 -0
- package/dist/api/article.d.ts.map +1 -0
- package/dist/api/article.js +43 -0
- package/dist/api/article.js.map +1 -0
- package/dist/api/asset.d.ts +28 -0
- package/dist/api/asset.d.ts.map +1 -0
- package/dist/api/asset.js +56 -0
- package/dist/api/asset.js.map +1 -0
- package/dist/api/banner.d.ts +8 -0
- package/dist/api/banner.d.ts.map +1 -0
- package/dist/api/banner.js +96 -0
- package/dist/api/banner.js.map +1 -0
- package/dist/api/breadcrumb.d.ts +40 -0
- package/dist/api/breadcrumb.d.ts.map +1 -0
- package/dist/api/breadcrumb.js +60 -0
- package/dist/api/breadcrumb.js.map +1 -0
- package/dist/api/componentPreview.d.ts +59 -0
- package/dist/api/componentPreview.d.ts.map +1 -0
- package/dist/api/componentPreview.js +88 -0
- package/dist/api/componentPreview.js.map +1 -0
- package/dist/api/context.d.ts +24 -0
- package/dist/api/context.d.ts.map +1 -0
- package/dist/api/context.js +73 -0
- package/dist/api/context.js.map +1 -0
- package/dist/api/custom-type.d.ts +37 -0
- package/dist/api/custom-type.d.ts.map +1 -0
- package/dist/api/custom-type.js +44 -0
- package/dist/api/custom-type.js.map +1 -0
- package/dist/api/document.d.ts +8 -0
- package/dist/api/document.d.ts.map +1 -0
- package/dist/api/document.js +84 -0
- package/dist/api/document.js.map +1 -0
- package/dist/api/helpers.d.ts +59 -0
- package/dist/api/helpers.d.ts.map +1 -0
- package/dist/api/helpers.js +313 -0
- package/dist/api/helpers.js.map +1 -0
- package/dist/api/index.d.ts +33 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +37 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/links.d.ts +124 -0
- package/dist/api/links.d.ts.map +1 -0
- package/dist/api/links.js +307 -0
- package/dist/api/links.js.map +1 -0
- package/dist/api/listing-fetch-params.d.ts +70 -0
- package/dist/api/listing-fetch-params.d.ts.map +1 -0
- package/dist/api/listing-fetch-params.js +124 -0
- package/dist/api/listing-fetch-params.js.map +1 -0
- package/dist/api/media-library.d.ts +59 -0
- package/dist/api/media-library.d.ts.map +1 -0
- package/dist/api/media-library.js +315 -0
- package/dist/api/media-library.js.map +1 -0
- package/dist/api/navigation.d.ts +10 -0
- package/dist/api/navigation.d.ts.map +1 -0
- package/dist/api/navigation.js +18 -0
- package/dist/api/navigation.js.map +1 -0
- package/dist/api/page.d.ts +15 -0
- package/dist/api/page.d.ts.map +1 -0
- package/dist/api/page.js +39 -0
- package/dist/api/page.js.map +1 -0
- package/dist/api/person.d.ts +37 -0
- package/dist/api/person.d.ts.map +1 -0
- package/dist/api/person.js +135 -0
- package/dist/api/person.js.map +1 -0
- package/dist/api/preview-types.d.ts +65 -0
- package/dist/api/preview-types.d.ts.map +1 -0
- package/dist/api/preview-types.js +7 -0
- package/dist/api/preview-types.js.map +1 -0
- package/dist/api/preview.d.ts +49 -0
- package/dist/api/preview.d.ts.map +1 -0
- package/dist/api/preview.js +261 -0
- package/dist/api/preview.js.map +1 -0
- package/dist/api/redirects.d.ts +16 -0
- package/dist/api/redirects.d.ts.map +1 -0
- package/dist/api/redirects.js +110 -0
- package/dist/api/redirects.js.map +1 -0
- package/dist/api/related-articles.d.ts +28 -0
- package/dist/api/related-articles.d.ts.map +1 -0
- package/dist/api/related-articles.js +147 -0
- package/dist/api/related-articles.js.map +1 -0
- package/dist/api/server-asset.d.ts +67 -0
- package/dist/api/server-asset.d.ts.map +1 -0
- package/dist/api/server-asset.js +106 -0
- package/dist/api/server-asset.js.map +1 -0
- package/dist/api/sitemap.d.ts +131 -0
- package/dist/api/sitemap.d.ts.map +1 -0
- package/dist/api/sitemap.js +201 -0
- package/dist/api/sitemap.js.map +1 -0
- package/dist/api/tag-type.d.ts +32 -0
- package/dist/api/tag-type.d.ts.map +1 -0
- package/dist/api/tag-type.js +123 -0
- package/dist/api/tag-type.js.map +1 -0
- package/dist/api/tag.d.ts +37 -0
- package/dist/api/tag.d.ts.map +1 -0
- package/dist/api/tag.js +132 -0
- package/dist/api/tag.js.map +1 -0
- package/dist/api/template.d.ts +61 -0
- package/dist/api/template.d.ts.map +1 -0
- package/dist/api/template.js +94 -0
- package/dist/api/template.js.map +1 -0
- package/dist/api/types.d.ts +113 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/baseTypes/baseAlternatePageContent.d.ts +32 -0
- package/dist/baseTypes/baseAlternatePageContent.d.ts.map +1 -0
- package/dist/baseTypes/baseAlternatePageContent.js +2 -0
- package/dist/baseTypes/baseAlternatePageContent.js.map +1 -0
- package/dist/baseTypes/baseArticle.d.ts +206 -0
- package/dist/baseTypes/baseArticle.d.ts.map +1 -0
- package/dist/baseTypes/baseArticle.js +2 -0
- package/dist/baseTypes/baseArticle.js.map +1 -0
- package/dist/baseTypes/baseArticleType.d.ts +177 -0
- package/dist/baseTypes/baseArticleType.d.ts.map +1 -0
- package/dist/baseTypes/baseArticleType.js +2 -0
- package/dist/baseTypes/baseArticleType.js.map +1 -0
- package/dist/baseTypes/baseBanner.d.ts +113 -0
- package/dist/baseTypes/baseBanner.d.ts.map +1 -0
- package/dist/baseTypes/baseBanner.js +2 -0
- package/dist/baseTypes/baseBanner.js.map +1 -0
- package/dist/baseTypes/baseCollection.d.ts +132 -0
- package/dist/baseTypes/baseCollection.d.ts.map +1 -0
- package/dist/baseTypes/baseCollection.js +2 -0
- package/dist/baseTypes/baseCollection.js.map +1 -0
- package/dist/baseTypes/baseComponent.d.ts +130 -0
- package/dist/baseTypes/baseComponent.d.ts.map +1 -0
- package/dist/baseTypes/baseComponent.js +2 -0
- package/dist/baseTypes/baseComponent.js.map +1 -0
- package/dist/baseTypes/baseCustomType.d.ts +147 -0
- package/dist/baseTypes/baseCustomType.d.ts.map +1 -0
- package/dist/baseTypes/baseCustomType.js +2 -0
- package/dist/baseTypes/baseCustomType.js.map +1 -0
- package/dist/baseTypes/baseDocument.d.ts +70 -0
- package/dist/baseTypes/baseDocument.d.ts.map +1 -0
- package/dist/baseTypes/baseDocument.js +2 -0
- package/dist/baseTypes/baseDocument.js.map +1 -0
- package/dist/baseTypes/baseExternalComponent.d.ts +138 -0
- package/dist/baseTypes/baseExternalComponent.d.ts.map +1 -0
- package/dist/baseTypes/baseExternalComponent.js +2 -0
- package/dist/baseTypes/baseExternalComponent.js.map +1 -0
- package/dist/baseTypes/baseExternalVideo.d.ts +86 -0
- package/dist/baseTypes/baseExternalVideo.d.ts.map +1 -0
- package/dist/baseTypes/baseExternalVideo.js +2 -0
- package/dist/baseTypes/baseExternalVideo.js.map +1 -0
- package/dist/baseTypes/baseHtmlComponent.d.ts +72 -0
- package/dist/baseTypes/baseHtmlComponent.d.ts.map +1 -0
- package/dist/baseTypes/baseHtmlComponent.js +2 -0
- package/dist/baseTypes/baseHtmlComponent.js.map +1 -0
- package/dist/baseTypes/baseLink.d.ts +115 -0
- package/dist/baseTypes/baseLink.d.ts.map +1 -0
- package/dist/baseTypes/baseLink.js +2 -0
- package/dist/baseTypes/baseLink.js.map +1 -0
- package/dist/baseTypes/baseMedia.d.ts +100 -0
- package/dist/baseTypes/baseMedia.d.ts.map +1 -0
- package/dist/baseTypes/baseMedia.js +2 -0
- package/dist/baseTypes/baseMedia.js.map +1 -0
- package/dist/baseTypes/baseNavigation.d.ts +37 -0
- package/dist/baseTypes/baseNavigation.d.ts.map +1 -0
- package/dist/baseTypes/baseNavigation.js +2 -0
- package/dist/baseTypes/baseNavigation.js.map +1 -0
- package/dist/baseTypes/baseNavigationItem.d.ts +109 -0
- package/dist/baseTypes/baseNavigationItem.d.ts.map +1 -0
- package/dist/baseTypes/baseNavigationItem.js +2 -0
- package/dist/baseTypes/baseNavigationItem.js.map +1 -0
- package/dist/baseTypes/basePage.d.ts +142 -0
- package/dist/baseTypes/basePage.d.ts.map +1 -0
- package/dist/baseTypes/basePage.js +2 -0
- package/dist/baseTypes/basePage.js.map +1 -0
- package/dist/baseTypes/basePageVariant.d.ts +145 -0
- package/dist/baseTypes/basePageVariant.d.ts.map +1 -0
- package/dist/baseTypes/basePageVariant.js +2 -0
- package/dist/baseTypes/basePageVariant.js.map +1 -0
- package/dist/baseTypes/basePerson.d.ts +160 -0
- package/dist/baseTypes/basePerson.d.ts.map +1 -0
- package/dist/baseTypes/basePerson.js +2 -0
- package/dist/baseTypes/basePerson.js.map +1 -0
- package/dist/baseTypes/baseRedirect.d.ts +69 -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/baseTypes/baseSchema.d.ts +19 -0
- package/dist/baseTypes/baseSchema.d.ts.map +1 -0
- package/dist/baseTypes/baseSchema.js +2 -0
- package/dist/baseTypes/baseSchema.js.map +1 -0
- package/dist/baseTypes/baseShared.d.ts +25 -0
- package/dist/baseTypes/baseShared.d.ts.map +1 -0
- package/dist/baseTypes/baseShared.js +2 -0
- package/dist/baseTypes/baseShared.js.map +1 -0
- package/dist/baseTypes/baseTag.d.ts +129 -0
- package/dist/baseTypes/baseTag.d.ts.map +1 -0
- package/dist/baseTypes/baseTag.js +2 -0
- package/dist/baseTypes/baseTag.js.map +1 -0
- package/dist/baseTypes/baseTagType.d.ts +70 -0
- package/dist/baseTypes/baseTagType.d.ts.map +1 -0
- package/dist/baseTypes/baseTagType.js +2 -0
- package/dist/baseTypes/baseTagType.js.map +1 -0
- package/dist/baseTypes/baseTemplate.d.ts +77 -0
- package/dist/baseTypes/baseTemplate.d.ts.map +1 -0
- package/dist/baseTypes/baseTemplate.js +2 -0
- package/dist/baseTypes/baseTemplate.js.map +1 -0
- package/dist/client.d.ts +145 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +322 -0
- package/dist/client.js.map +1 -0
- package/dist/cms-integrity.d.ts +10 -0
- package/dist/cms-integrity.d.ts.map +1 -0
- package/dist/cms-integrity.js +7 -0
- package/dist/cms-integrity.js.map +1 -0
- package/dist/converters/animationEnricher.d.ts +17 -0
- package/dist/converters/animationEnricher.d.ts.map +1 -0
- package/dist/converters/animationEnricher.js +177 -0
- package/dist/converters/animationEnricher.js.map +1 -0
- package/dist/converters/article.d.ts +48 -0
- package/dist/converters/article.d.ts.map +1 -0
- package/dist/converters/article.js +364 -0
- package/dist/converters/article.js.map +1 -0
- package/dist/converters/asset.d.ts +33 -0
- package/dist/converters/asset.d.ts.map +1 -0
- package/dist/converters/asset.js +340 -0
- package/dist/converters/asset.js.map +1 -0
- package/dist/converters/banner.d.ts +10 -0
- package/dist/converters/banner.d.ts.map +1 -0
- package/dist/converters/banner.js +63 -0
- package/dist/converters/banner.js.map +1 -0
- package/dist/converters/collection.d.ts +26 -0
- package/dist/converters/collection.d.ts.map +1 -0
- package/dist/converters/collection.js +52 -0
- package/dist/converters/collection.js.map +1 -0
- package/dist/converters/component.d.ts +26 -0
- package/dist/converters/component.d.ts.map +1 -0
- package/dist/converters/component.js +54 -0
- package/dist/converters/component.js.map +1 -0
- package/dist/converters/customType.d.ts +24 -0
- package/dist/converters/customType.d.ts.map +1 -0
- package/dist/converters/customType.js +93 -0
- package/dist/converters/customType.js.map +1 -0
- package/dist/converters/document.d.ts +14 -0
- package/dist/converters/document.d.ts.map +1 -0
- package/dist/converters/document.js +51 -0
- package/dist/converters/document.js.map +1 -0
- package/dist/converters/enrichAssets.d.ts +19 -0
- package/dist/converters/enrichAssets.d.ts.map +1 -0
- package/dist/converters/enrichAssets.js +36 -0
- package/dist/converters/enrichAssets.js.map +1 -0
- package/dist/converters/externalComponent.d.ts +27 -0
- package/dist/converters/externalComponent.d.ts.map +1 -0
- package/dist/converters/externalComponent.js +46 -0
- package/dist/converters/externalComponent.js.map +1 -0
- package/dist/converters/externalVideoEnricher.d.ts +12 -0
- package/dist/converters/externalVideoEnricher.d.ts.map +1 -0
- package/dist/converters/externalVideoEnricher.js +70 -0
- package/dist/converters/externalVideoEnricher.js.map +1 -0
- package/dist/converters/helpers.d.ts +173 -0
- package/dist/converters/helpers.d.ts.map +1 -0
- package/dist/converters/helpers.js +167 -0
- package/dist/converters/helpers.js.map +1 -0
- package/dist/converters/heroVideoEnricher.d.ts +9 -0
- package/dist/converters/heroVideoEnricher.d.ts.map +1 -0
- package/dist/converters/heroVideoEnricher.js +108 -0
- package/dist/converters/heroVideoEnricher.js.map +1 -0
- package/dist/converters/heroVideoEnv.d.ts +14 -0
- package/dist/converters/heroVideoEnv.d.ts.map +1 -0
- package/dist/converters/heroVideoEnv.js +28 -0
- package/dist/converters/heroVideoEnv.js.map +1 -0
- package/dist/converters/htmlComponent.d.ts +17 -0
- package/dist/converters/htmlComponent.d.ts.map +1 -0
- package/dist/converters/htmlComponent.js +33 -0
- package/dist/converters/htmlComponent.js.map +1 -0
- package/dist/converters/iconCollector.d.ts +36 -0
- package/dist/converters/iconCollector.d.ts.map +1 -0
- package/dist/converters/iconCollector.js +309 -0
- package/dist/converters/iconCollector.js.map +1 -0
- package/dist/converters/index.d.ts +26 -0
- package/dist/converters/index.d.ts.map +1 -0
- package/dist/converters/index.js +21 -0
- package/dist/converters/index.js.map +1 -0
- package/dist/converters/link.d.ts +11 -0
- package/dist/converters/link.d.ts.map +1 -0
- package/dist/converters/link.js +109 -0
- package/dist/converters/link.js.map +1 -0
- package/dist/converters/navigationItem.d.ts +17 -0
- package/dist/converters/navigationItem.d.ts.map +1 -0
- package/dist/converters/navigationItem.js +126 -0
- package/dist/converters/navigationItem.js.map +1 -0
- package/dist/converters/page.d.ts +44 -0
- package/dist/converters/page.d.ts.map +1 -0
- package/dist/converters/page.js +160 -0
- package/dist/converters/page.js.map +1 -0
- package/dist/converters/pageVariantMerge.d.ts +24 -0
- package/dist/converters/pageVariantMerge.d.ts.map +1 -0
- package/dist/converters/pageVariantMerge.js +151 -0
- package/dist/converters/pageVariantMerge.js.map +1 -0
- package/dist/converters/person.d.ts +40 -0
- package/dist/converters/person.d.ts.map +1 -0
- package/dist/converters/person.js +152 -0
- package/dist/converters/person.js.map +1 -0
- package/dist/converters/pictureBlurEnricher.d.ts +9 -0
- package/dist/converters/pictureBlurEnricher.d.ts.map +1 -0
- package/dist/converters/pictureBlurEnricher.js +79 -0
- package/dist/converters/pictureBlurEnricher.js.map +1 -0
- package/dist/converters/redirect.d.ts +20 -0
- package/dist/converters/redirect.d.ts.map +1 -0
- package/dist/converters/redirect.js +50 -0
- package/dist/converters/redirect.js.map +1 -0
- package/dist/converters/resolver.d.ts +26 -0
- package/dist/converters/resolver.d.ts.map +1 -0
- package/dist/converters/resolver.js +383 -0
- package/dist/converters/resolver.js.map +1 -0
- package/dist/converters/schema.d.ts +14 -0
- package/dist/converters/schema.d.ts.map +1 -0
- package/dist/converters/schema.js +25 -0
- package/dist/converters/schema.js.map +1 -0
- package/dist/converters/svgProcessor.d.ts +58 -0
- package/dist/converters/svgProcessor.d.ts.map +1 -0
- package/dist/converters/svgProcessor.js +225 -0
- package/dist/converters/svgProcessor.js.map +1 -0
- package/dist/converters/tag.d.ts +25 -0
- package/dist/converters/tag.d.ts.map +1 -0
- package/dist/converters/tag.js +170 -0
- package/dist/converters/tag.js.map +1 -0
- package/dist/converters/tagType.d.ts +15 -0
- package/dist/converters/tagType.d.ts.map +1 -0
- package/dist/converters/tagType.js +56 -0
- package/dist/converters/tagType.js.map +1 -0
- package/dist/converters/template.d.ts +31 -0
- package/dist/converters/template.d.ts.map +1 -0
- package/dist/converters/template.js +53 -0
- package/dist/converters/template.js.map +1 -0
- package/dist/converters/videoEnricher.d.ts +14 -0
- package/dist/converters/videoEnricher.d.ts.map +1 -0
- package/dist/converters/videoEnricher.js +85 -0
- package/dist/converters/videoEnricher.js.map +1 -0
- package/dist/icons/rebuildIconSprite.d.ts +8 -0
- package/dist/icons/rebuildIconSprite.d.ts.map +1 -0
- package/dist/icons/rebuildIconSprite.js +15 -0
- package/dist/icons/rebuildIconSprite.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation/assembly.d.ts +8 -0
- package/dist/navigation/assembly.d.ts.map +1 -0
- package/dist/navigation/assembly.js +115 -0
- package/dist/navigation/assembly.js.map +1 -0
- package/dist/navigation/cacheOptions.d.ts +17 -0
- package/dist/navigation/cacheOptions.d.ts.map +1 -0
- package/dist/navigation/cacheOptions.js +45 -0
- package/dist/navigation/cacheOptions.js.map +1 -0
- package/dist/navigation/enrichModelNavigation.d.ts +17 -0
- package/dist/navigation/enrichModelNavigation.d.ts.map +1 -0
- package/dist/navigation/enrichModelNavigation.js +46 -0
- package/dist/navigation/enrichModelNavigation.js.map +1 -0
- package/dist/navigation/linkIndex.d.ts +10 -0
- package/dist/navigation/linkIndex.d.ts.map +1 -0
- package/dist/navigation/linkIndex.js +34 -0
- package/dist/navigation/linkIndex.js.map +1 -0
- package/dist/navigation/listingLinkBundle.d.ts +22 -0
- package/dist/navigation/listingLinkBundle.d.ts.map +1 -0
- package/dist/navigation/listingLinkBundle.js +88 -0
- package/dist/navigation/listingLinkBundle.js.map +1 -0
- package/dist/navigation/registry.d.ts +15 -0
- package/dist/navigation/registry.d.ts.map +1 -0
- package/dist/navigation/registry.js +130 -0
- package/dist/navigation/registry.js.map +1 -0
- package/dist/navigation/requestCache.d.ts +18 -0
- package/dist/navigation/requestCache.d.ts.map +1 -0
- package/dist/navigation/requestCache.js +66 -0
- package/dist/navigation/requestCache.js.map +1 -0
- package/dist/navigation/types.d.ts +45 -0
- package/dist/navigation/types.d.ts.map +1 -0
- package/dist/navigation/types.js +2 -0
- package/dist/navigation/types.js.map +1 -0
- package/dist/revalidation/entry-handlers.d.ts +40 -0
- package/dist/revalidation/entry-handlers.d.ts.map +1 -0
- package/dist/revalidation/entry-handlers.js +144 -0
- package/dist/revalidation/entry-handlers.js.map +1 -0
- package/dist/revalidation/handlers.d.ts +19 -0
- package/dist/revalidation/handlers.d.ts.map +1 -0
- package/dist/revalidation/handlers.js +50 -0
- package/dist/revalidation/handlers.js.map +1 -0
- package/dist/revalidation/index.d.ts +4 -0
- package/dist/revalidation/index.d.ts.map +1 -0
- package/dist/revalidation/index.js +5 -0
- package/dist/revalidation/index.js.map +1 -0
- package/dist/revalidation/nextjs-route.d.ts +38 -0
- package/dist/revalidation/nextjs-route.d.ts.map +1 -0
- package/dist/revalidation/nextjs-route.js +36 -0
- package/dist/revalidation/nextjs-route.js.map +1 -0
- package/dist/revalidation/route.d.ts +3 -0
- package/dist/revalidation/route.d.ts.map +1 -0
- package/dist/revalidation/route.js +99 -0
- package/dist/revalidation/route.js.map +1 -0
- package/dist/revalidation/server-utils.d.ts +31 -0
- package/dist/revalidation/server-utils.d.ts.map +1 -0
- package/dist/revalidation/server-utils.js +54 -0
- package/dist/revalidation/server-utils.js.map +1 -0
- package/dist/revalidation/tags.d.ts +110 -0
- package/dist/revalidation/tags.d.ts.map +1 -0
- package/dist/revalidation/tags.js +160 -0
- package/dist/revalidation/tags.js.map +1 -0
- package/dist/revalidation/utils.d.ts +21 -0
- package/dist/revalidation/utils.d.ts.map +1 -0
- package/dist/revalidation/utils.js +61 -0
- package/dist/revalidation/utils.js.map +1 -0
- package/dist/revalidation/webhook-content-types.d.ts +12 -0
- package/dist/revalidation/webhook-content-types.d.ts.map +1 -0
- package/dist/revalidation/webhook-content-types.js +28 -0
- package/dist/revalidation/webhook-content-types.js.map +1 -0
- package/dist/routing/index.d.ts +2 -0
- package/dist/routing/index.d.ts.map +1 -0
- package/dist/routing/index.js +2 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/marketing-site-url-calculators.d.ts +21 -0
- package/dist/routing/marketing-site-url-calculators.d.ts.map +1 -0
- package/dist/routing/marketing-site-url-calculators.js +43 -0
- package/dist/routing/marketing-site-url-calculators.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +10 -0
- package/dist/server.js.map +1 -0
- package/dist/telemetry/deriveOperation.d.ts +8 -0
- package/dist/telemetry/deriveOperation.d.ts.map +1 -0
- package/dist/telemetry/deriveOperation.js +59 -0
- package/dist/telemetry/deriveOperation.js.map +1 -0
- package/dist/telemetry/queryContext.d.ts +7 -0
- package/dist/telemetry/queryContext.d.ts.map +1 -0
- package/dist/telemetry/queryContext.js +9 -0
- package/dist/telemetry/queryContext.js.map +1 -0
- package/dist/telemetry/queryLog.d.ts +17 -0
- package/dist/telemetry/queryLog.d.ts.map +1 -0
- package/dist/telemetry/queryLog.js +54 -0
- package/dist/telemetry/queryLog.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/arrayUtils.d.ts +3 -0
- package/dist/utils/arrayUtils.d.ts.map +1 -0
- package/dist/utils/arrayUtils.js +12 -0
- package/dist/utils/arrayUtils.js.map +1 -0
- package/dist/utils/dateUtils.d.ts +9 -0
- package/dist/utils/dateUtils.d.ts.map +1 -0
- package/dist/utils/dateUtils.js +26 -0
- package/dist/utils/dateUtils.js.map +1 -0
- package/dist/utils/errors.d.ts +56 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +100 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/redirectMap.d.ts +40 -0
- package/dist/utils/redirectMap.d.ts.map +1 -0
- package/dist/utils/redirectMap.js +129 -0
- package/dist/utils/redirectMap.js.map +1 -0
- package/dist/utils/retry.d.ts +103 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +248 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/tags.d.ts +35 -0
- package/dist/utils/tags.d.ts.map +1 -0
- package/dist/utils/tags.js +37 -0
- package/dist/utils/tags.js.map +1 -0
- package/docs/llms.md +430 -0
- package/package.json +86 -0
package/README.md
ADDED
|
@@ -0,0 +1,764 @@
|
|
|
1
|
+
# @se-studio/contentful-rest-api
|
|
2
|
+
|
|
3
|
+
Type-safe Contentful REST API client with caching, rate limiting, and extensible converters for Next.js applications.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Features](#features)
|
|
8
|
+
- [Installation](#installation)
|
|
9
|
+
- [Quick Start](#quick-start)
|
|
10
|
+
- [Basic Usage](#basic-usage)
|
|
11
|
+
- [Preview Mode](#preview-mode)
|
|
12
|
+
- [API Reference](#api-reference)
|
|
13
|
+
- [Client Functions](#client-functions)
|
|
14
|
+
- [Content Fetching Functions](#content-fetching-functions)
|
|
15
|
+
- [Converter Pattern](#converter-pattern)
|
|
16
|
+
- [Base Converter](#base-converter)
|
|
17
|
+
- [Enhancers](#enhancers)
|
|
18
|
+
- [Custom Converters](#custom-converters)
|
|
19
|
+
- [Caching](#caching)
|
|
20
|
+
- [Cache Tags](#cache-tags)
|
|
21
|
+
- [Cache Revalidation](#cache-revalidation)
|
|
22
|
+
- [Error Handling](#error-handling)
|
|
23
|
+
- [Retry Configuration](#retry-configuration)
|
|
24
|
+
- [Rate Limiting](#rate-limiting)
|
|
25
|
+
- [Type Generation](#type-generation)
|
|
26
|
+
- [Configuration Options](#configuration-options)
|
|
27
|
+
- [ContentfulConfig](#contentfulconfig)
|
|
28
|
+
- [FetchOptions](#fetchoptions)
|
|
29
|
+
- [CacheConfig](#cacheconfig)
|
|
30
|
+
- [RetryConfig](#retryconfig)
|
|
31
|
+
- [Next.js App Router Integration](#nextjs-app-router-integration)
|
|
32
|
+
- [License](#license)
|
|
33
|
+
- [Repository](#repository)
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- 🎯 **Type-safe** - Full TypeScript support with generated types from your Contentful space
|
|
38
|
+
- 🔄 **Dual API Support** - Content Delivery API (CDA) and Content Preview API (CPA)
|
|
39
|
+
- ⚡ **Next.js Optimized** - Built-in support for Next.js App Router cache tags and revalidation
|
|
40
|
+
- 🔁 **Retry Logic** - Automatic retry with exponential backoff for failed requests
|
|
41
|
+
- 🚦 **Rate Limiting** - Respect Contentful API rate limits with built-in rate limiter
|
|
42
|
+
- 🧩 **Extensible Converters** - Functional composition pattern for customizing content transformations
|
|
43
|
+
- 🛡️ **Error Handling** - Custom error types for different failure scenarios
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pnpm add @se-studio/contentful-rest-api @se-studio/core-data-types contentful
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
### Basic Usage
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { contentfulPageRest } from '@se-studio/contentful-rest-api';
|
|
57
|
+
|
|
58
|
+
// Fetch a page by slug
|
|
59
|
+
const page = await contentfulPageRest(
|
|
60
|
+
{
|
|
61
|
+
spaceId: process.env.CONTENTFUL_SPACE_ID!,
|
|
62
|
+
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,
|
|
63
|
+
environment: 'master'
|
|
64
|
+
},
|
|
65
|
+
'home',
|
|
66
|
+
{
|
|
67
|
+
locale: 'en-US',
|
|
68
|
+
cache: {
|
|
69
|
+
tags: ['home-page'],
|
|
70
|
+
revalidate: 3600 // 1 hour
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Preview Mode
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { contentfulPageRest } from '@se-studio/contentful-rest-api';
|
|
80
|
+
|
|
81
|
+
// Use preview API for draft content
|
|
82
|
+
const page = await contentfulPageRest(
|
|
83
|
+
{
|
|
84
|
+
spaceId: process.env.CONTENTFUL_SPACE_ID!,
|
|
85
|
+
accessToken: process.env.CONTENTFUL_PREVIEW_ACCESS_TOKEN!,
|
|
86
|
+
},
|
|
87
|
+
'home',
|
|
88
|
+
{
|
|
89
|
+
preview: true, // Uses Preview API (CPA)
|
|
90
|
+
cache: {
|
|
91
|
+
cache: 'no-store' // Disable Next.js caching for preview content
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## API Reference
|
|
98
|
+
|
|
99
|
+
### Client Functions
|
|
100
|
+
|
|
101
|
+
#### `createContentfulClient(config)`
|
|
102
|
+
|
|
103
|
+
Creates a Contentful Content Delivery API (CDA) client.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { createContentfulClient } from '@se-studio/contentful-rest-api';
|
|
107
|
+
|
|
108
|
+
const client = createContentfulClient({
|
|
109
|
+
spaceId: process.env.CONTENTFUL_SPACE_ID!,
|
|
110
|
+
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,
|
|
111
|
+
environment: 'master'
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### `createContentfulPreviewClient(config)`
|
|
116
|
+
|
|
117
|
+
Creates a Contentful Content Preview API (CPA) client.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { createContentfulPreviewClient } from '@se-studio/contentful-rest-api';
|
|
121
|
+
|
|
122
|
+
const previewClient = createContentfulPreviewClient({
|
|
123
|
+
spaceId: process.env.CONTENTFUL_SPACE_ID!,
|
|
124
|
+
accessToken: process.env.CONTENTFUL_PREVIEW_ACCESS_TOKEN!,
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Content Fetching Functions
|
|
129
|
+
|
|
130
|
+
#### `contentfulPageRest(config, slug, options?, converter?)`
|
|
131
|
+
|
|
132
|
+
Fetches a page by slug.
|
|
133
|
+
|
|
134
|
+
**Parameters:**
|
|
135
|
+
- `config`: ContentfulConfig - Contentful client configuration
|
|
136
|
+
- `slug`: string - Page slug to fetch
|
|
137
|
+
- `options?`: FetchOptions - Optional fetch options (locale, preview, cache, retry)
|
|
138
|
+
- `converter?`: Converter - Optional custom converter function
|
|
139
|
+
|
|
140
|
+
**Returns:** `Promise<IPage | null>`
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
const page = await contentfulPageRest(
|
|
144
|
+
config,
|
|
145
|
+
'about-us',
|
|
146
|
+
{
|
|
147
|
+
locale: 'en-US',
|
|
148
|
+
include: 10,
|
|
149
|
+
cache: { tags: ['about-page'], revalidate: 3600 }
|
|
150
|
+
}
|
|
151
|
+
);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### `contentfulPageByIdRest(config, id, options?, converter?)`
|
|
155
|
+
|
|
156
|
+
Fetches a page by entry ID.
|
|
157
|
+
|
|
158
|
+
**Parameters:**
|
|
159
|
+
- `config`: ContentfulConfig
|
|
160
|
+
- `id`: string - Entry ID
|
|
161
|
+
- `options?`: FetchOptions
|
|
162
|
+
- `converter?`: Converter
|
|
163
|
+
|
|
164
|
+
**Returns:** `Promise<IPage>`
|
|
165
|
+
|
|
166
|
+
**Throws:** `EntryNotFoundError` if entry doesn't exist
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const page = await contentfulPageByIdRest(
|
|
170
|
+
config,
|
|
171
|
+
'5nZHNlP9rZhWvKx4w2Z8zB'
|
|
172
|
+
);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### `contentfulAllPagesRest(config, options?, converter?)`
|
|
176
|
+
|
|
177
|
+
Fetches all pages from Contentful.
|
|
178
|
+
|
|
179
|
+
**Parameters:**
|
|
180
|
+
- `config`: ContentfulConfig
|
|
181
|
+
- `options?`: FetchOptions
|
|
182
|
+
- `converter?`: Converter
|
|
183
|
+
|
|
184
|
+
**Returns:** `Promise<IPage[]>`
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const pages = await contentfulAllPagesRest(
|
|
188
|
+
config,
|
|
189
|
+
{
|
|
190
|
+
locale: 'en-US',
|
|
191
|
+
cache: { tags: ['all-pages'], revalidate: 3600 }
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### `contentfulEntryRest<TEntry, TResult>(config, id, converter, options?)`
|
|
197
|
+
|
|
198
|
+
Generic function to fetch any entry type with a custom converter.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
const article = await contentfulEntryRest(
|
|
202
|
+
config,
|
|
203
|
+
'articleId123',
|
|
204
|
+
myArticleConverter,
|
|
205
|
+
{ locale: 'en-US' }
|
|
206
|
+
);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Converter Pattern
|
|
210
|
+
|
|
211
|
+
The package uses a functional composition pattern for converting Contentful entries to your domain types.
|
|
212
|
+
|
|
213
|
+
### Base Converter
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { basePageConverter } from '@se-studio/contentful-rest-api';
|
|
217
|
+
|
|
218
|
+
// Use the base converter
|
|
219
|
+
const page = basePageConverter(contentfulEntry);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Enhancers
|
|
223
|
+
|
|
224
|
+
Enhancers are functions that wrap converters to add additional functionality:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import {
|
|
228
|
+
basePageConverter,
|
|
229
|
+
withSEO,
|
|
230
|
+
withSections,
|
|
231
|
+
withTags,
|
|
232
|
+
compose
|
|
233
|
+
} from '@se-studio/contentful-rest-api';
|
|
234
|
+
|
|
235
|
+
// Compose multiple enhancers
|
|
236
|
+
const myConverter = compose(
|
|
237
|
+
withSEO,
|
|
238
|
+
withSections,
|
|
239
|
+
withTags
|
|
240
|
+
)(basePageConverter);
|
|
241
|
+
|
|
242
|
+
// Use with API functions
|
|
243
|
+
const page = await contentfulPageRest(config, 'home', {}, myConverter);
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Custom Converters
|
|
247
|
+
|
|
248
|
+
Create your own converter enhancers:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
import type { Converter, PageEntrySkeleton } from '@se-studio/contentful-rest-api';
|
|
252
|
+
import type { IPage } from '@se-studio/core-data-types';
|
|
253
|
+
|
|
254
|
+
function withCustomField(
|
|
255
|
+
converter: Converter<PageEntrySkeleton, IPage>
|
|
256
|
+
): Converter<PageEntrySkeleton, IPage> {
|
|
257
|
+
return (entry) => {
|
|
258
|
+
const page = converter(entry);
|
|
259
|
+
|
|
260
|
+
// Add custom logic
|
|
261
|
+
return {
|
|
262
|
+
...page,
|
|
263
|
+
customField: entry.fields.customField || 'default'
|
|
264
|
+
};
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Use it
|
|
269
|
+
const converter = withCustomField(basePageConverter);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Caching
|
|
273
|
+
|
|
274
|
+
### Flat navigation
|
|
275
|
+
|
|
276
|
+
Menus are assembled in memory from a flat registry of `navigationItem` / `navigation` entries plus a bulk internal-link index — no deep Contentful `include` chain.
|
|
277
|
+
|
|
278
|
+
**Preferred for page renders:** set `navigationResolution: 'flat'` on `FetchOptions` (e.g. in app `buildOptions`). Entity fetches stub nav root ids during conversion, then assemble full menu/footer trees post-convert and rebuild icon sprites. Layouts receive a complete model — no layout-time `getNavigation` bridge.
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
// app cms-server buildOptions
|
|
282
|
+
buildFetchOptions({ navigationResolution: 'flat', ...options }, preview);
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**Ad hoc assembly:** call `getNavigation(navigationId)` from `createAppHelpers` in `@se-studio/core-ui` when you only need a menu by id. Do not call registry or link-index fetchers from layouts; those are package-internal.
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
const menu = await helpers.getNavigation(mainNavId);
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Default is `navigationResolution: 'bundled'` (resolve menu/footer via Contentful includes during conversion).
|
|
292
|
+
|
|
293
|
+
`getNavigation` applies `buildFlatNavigationCacheOptions()`:
|
|
294
|
+
|
|
295
|
+
- **Tag invalidation (primary):** every sub-fetch is tagged with `FLAT_NAV_CACHE_TAGS` (navigation, navigationItem, page, article, tag, **tagType**, **link**, etc.) so Contentful webhooks can invalidate menus when any routable entry changes.
|
|
296
|
+
- **Time revalidation (fallback):** `FLAT_NAV_TIME_REVALIDATE_SECONDS` (3600) when a webhook is missed. Override with `options.next.revalidate` (`false` for tag-only caching).
|
|
297
|
+
|
|
298
|
+
Unresolved internal nav targets render as blank links and log under `LOG_CMS=1`.
|
|
299
|
+
|
|
300
|
+
### Golden listing fields
|
|
301
|
+
|
|
302
|
+
Bulk link fetches (`fetchProfile: 'listing'`) use field `select` lists documented in `listing-fetch-params.ts`. Spaces that omit optional fields will 422 — trim per content type in the consumer, or omit `select` for schema-tolerant registry fetches.
|
|
303
|
+
|
|
304
|
+
`tagType` link fetches request `fields.slug` (important for customer URL schemes). Spaces without `slug` automatically retry with minimal fields (`name`, `show`).
|
|
305
|
+
|
|
306
|
+
### Cache Tags
|
|
307
|
+
|
|
308
|
+
The package automatically manages cache tags for Next.js App Router. Tags follow a consistent naming convention:
|
|
309
|
+
|
|
310
|
+
- **Individual entries**: `{contentType}#{slug}` (e.g., `page#home`, `article#my-post`)
|
|
311
|
+
- **Collections**: `{contentType}` (e.g., `page`, `article`, `articleType`)
|
|
312
|
+
- **Preview mode**: `global` (single tag for all content when preview mode is enabled)
|
|
313
|
+
|
|
314
|
+
**Publish cascades (coarse):** `template` publish also revalidates `page` + `article`; `articleType` → `article`; `customType` → `tag` + `person`. See `docs/CONTENTFUL_WEBHOOK_REVALIDATION.md`.
|
|
315
|
+
|
|
316
|
+
### Automatic Cache Tagging
|
|
317
|
+
|
|
318
|
+
All content fetching functions automatically apply appropriate cache tags based on the `preview` flag:
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
import { contentfulPageRest, contentfulArticleRest } from '@se-studio/contentful-rest-api';
|
|
322
|
+
|
|
323
|
+
// Production mode: tagged with ['page#home', 'page']
|
|
324
|
+
const page = await contentfulPageRest(config, 'home', { preview: false });
|
|
325
|
+
|
|
326
|
+
// Preview mode: tagged with ['global']
|
|
327
|
+
const previewPage = await contentfulPageRest(config, 'home', { preview: true });
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Preview Mode
|
|
331
|
+
|
|
332
|
+
When `preview: true` is passed to fetch functions or revalidation:
|
|
333
|
+
- All content uses the `global` cache tag
|
|
334
|
+
- Revalidation always clears the `global` tag
|
|
335
|
+
- No time-based revalidation
|
|
336
|
+
|
|
337
|
+
### Cache Revalidation
|
|
338
|
+
|
|
339
|
+
#### Webhook Integration
|
|
340
|
+
|
|
341
|
+
Set up Contentful webhooks to automatically revalidate cache when content changes:
|
|
342
|
+
|
|
343
|
+
1. **Create API Route** in your Next.js app:
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
// app/api/revalidate/route.ts
|
|
347
|
+
import { createRevalidationHandler } from '@se-studio/contentful-rest-api';
|
|
348
|
+
|
|
349
|
+
export const POST = createRevalidationHandler({
|
|
350
|
+
secret: process.env.REVALIDATION_SECRET,
|
|
351
|
+
validateSecret: true,
|
|
352
|
+
preview: process.env.DRAFT_ONLY === 'true', // or from your config
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
2. **Configure Contentful Webhook**:
|
|
357
|
+
- URL: `https://yourdomain.com/api/revalidate`
|
|
358
|
+
- Secret: Set `REVALIDATION_SECRET` environment variable
|
|
359
|
+
- Triggers: Select content types to monitor (pages, articles, etc.)
|
|
360
|
+
|
|
361
|
+
3. **Required Environment Variables**:
|
|
362
|
+
```bash
|
|
363
|
+
REVALIDATION_SECRET=your-webhook-secret
|
|
364
|
+
CONTENTFUL_MANAGEMENT_TOKEN=your-management-token
|
|
365
|
+
CONTENTFUL_SPACE_ID=your-space-id
|
|
366
|
+
CONTENTFUL_ENVIRONMENT_NAME=your-environment
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
#### Manual Revalidation
|
|
370
|
+
|
|
371
|
+
Revalidate cache tags programmatically:
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
'use server'
|
|
375
|
+
|
|
376
|
+
import { revalidateTags, revalidateSingleTag } from '@se-studio/contentful-rest-api';
|
|
377
|
+
|
|
378
|
+
// Revalidate multiple tags
|
|
379
|
+
await revalidateTags(['page#home', 'page'], 'manual revalidation');
|
|
380
|
+
|
|
381
|
+
// Revalidate single tag
|
|
382
|
+
await revalidateSingleTag('article#my-post', 'article updated');
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
#### Bulk Revalidation
|
|
386
|
+
|
|
387
|
+
Trigger full cache revalidation:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
# Via HTTP request
|
|
391
|
+
curl -X POST https://yourdomain.com/api/revalidate \
|
|
392
|
+
-H "REVALIDATE_ALL: true"
|
|
393
|
+
|
|
394
|
+
# Via single tag
|
|
395
|
+
curl -X POST https://yourdomain.com/api/revalidate \
|
|
396
|
+
-H "REVALIDATION_TAG: global"
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Content Type Support
|
|
400
|
+
|
|
401
|
+
The revalidation system supports these content types:
|
|
402
|
+
|
|
403
|
+
- **Pages**: `page` (individual: `page#{slug}`, collection: `page`)
|
|
404
|
+
- **Page variants**: `pageVariant` (individual: `pageVariant#{slug}`, collection: `pageVariant`)
|
|
405
|
+
- **Articles**: `article` (individual: `article#{slug}`, collection: `article`)
|
|
406
|
+
- **Article Types**: `articleType` (individual: `articleType#{slug}`, collection: `articleType`)
|
|
407
|
+
- **Custom Types**: `customType` (collection only: `customType`)
|
|
408
|
+
- **Tags**: `tag` (individual: `tag#{slug}`, collection: `tag`)
|
|
409
|
+
- **Tag types**: `tagType` (individual: `tagType#{slug}`, collection: `tagType`)
|
|
410
|
+
- **Link wrappers**: `link` (collection: `link`)
|
|
411
|
+
- **Navigation**: `navigation`, `navigationItem` (collection tags; required for flat-nav invalidation)
|
|
412
|
+
- **People**: `person` (individual: `person#{slug}`, collection: `person`)
|
|
413
|
+
- **Templates**: `template` (individual: `template#{cmsLabel}`, collection: `template`)
|
|
414
|
+
- **Banners**: `banner` (collection: `banner`)
|
|
415
|
+
- **Assets**: `asset` (individual: `asset#{id}`, collection: `asset`; separate asset webhook in setup scripts)
|
|
416
|
+
- **Locations**: `location` (individual: `location#{slug}`, collection: `location`)
|
|
417
|
+
|
|
418
|
+
**Production webhook filter:** use `REVALIDATION_WEBHOOK_ENTRY_CONTENT_TYPES` or `REVALIDATION_WEBHOOK_ENTRY_CONTENT_TYPES_CSV` from this package (see `docs/CONTENTFUL_WEBHOOK_REVALIDATION.md`). `redirect` is excluded — it uses a Vercel deploy hook.
|
|
419
|
+
|
|
420
|
+
### Tag Functions
|
|
421
|
+
|
|
422
|
+
Access tag generation functions directly:
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import {
|
|
426
|
+
pageTag,
|
|
427
|
+
articleTag,
|
|
428
|
+
articleTypeTag,
|
|
429
|
+
PageTag,
|
|
430
|
+
ArticleTag,
|
|
431
|
+
AllTags
|
|
432
|
+
} from '@se-studio/contentful-rest-api';
|
|
433
|
+
|
|
434
|
+
// Individual tags
|
|
435
|
+
const homePageTag = pageTag('home'); // 'page#home'
|
|
436
|
+
const blogPostTag = articleTag('my-post'); // 'article#my-post'
|
|
437
|
+
|
|
438
|
+
// Collection tags
|
|
439
|
+
const allPagesTag = PageTag; // 'page'
|
|
440
|
+
const allArticlesTag = ArticleTag; // 'article'
|
|
441
|
+
|
|
442
|
+
// All available tags
|
|
443
|
+
console.log(AllTags); // ['page', 'article', 'articleType', ...]
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
## Error Handling
|
|
447
|
+
|
|
448
|
+
The package provides custom error types for different scenarios:
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
import {
|
|
452
|
+
ContentfulError,
|
|
453
|
+
RateLimitError,
|
|
454
|
+
EntryNotFoundError,
|
|
455
|
+
AuthenticationError,
|
|
456
|
+
ValidationError,
|
|
457
|
+
isRetryableError
|
|
458
|
+
} from '@se-studio/contentful-rest-api';
|
|
459
|
+
|
|
460
|
+
try {
|
|
461
|
+
const page = await contentfulPageByIdRest(config, 'invalid-id');
|
|
462
|
+
} catch (error) {
|
|
463
|
+
if (error instanceof EntryNotFoundError) {
|
|
464
|
+
console.log('Entry not found:', error.entryId);
|
|
465
|
+
} else if (error instanceof RateLimitError) {
|
|
466
|
+
console.log('Rate limited, retry after:', error.retryAfter);
|
|
467
|
+
} else if (isRetryableError(error)) {
|
|
468
|
+
// Handle retryable errors
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Retry Configuration
|
|
474
|
+
|
|
475
|
+
Configure retry behavior for resilient API calls:
|
|
476
|
+
|
|
477
|
+
```typescript
|
|
478
|
+
const page = await contentfulPageRest(
|
|
479
|
+
config,
|
|
480
|
+
'home',
|
|
481
|
+
{
|
|
482
|
+
retry: {
|
|
483
|
+
maxRetries: 3,
|
|
484
|
+
initialDelay: 1000,
|
|
485
|
+
maxDelay: 30000,
|
|
486
|
+
backoffMultiplier: 2
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
);
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Rate Limiting
|
|
493
|
+
|
|
494
|
+
Use the built-in rate limiter to control request rates:
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
import { RateLimiter } from '@se-studio/contentful-rest-api';
|
|
498
|
+
|
|
499
|
+
// Create a rate limiter (5 requests per second)
|
|
500
|
+
const limiter = new RateLimiter(5, 1);
|
|
501
|
+
|
|
502
|
+
// Consume a token before making a request
|
|
503
|
+
await limiter.consume();
|
|
504
|
+
const page = await contentfulPageRest(config, 'home');
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Type Generation
|
|
508
|
+
|
|
509
|
+
Generate TypeScript types from your Contentful space:
|
|
510
|
+
|
|
511
|
+
### 1. Configure Environment Variables
|
|
512
|
+
|
|
513
|
+
Create a `.env.local` file:
|
|
514
|
+
|
|
515
|
+
```env
|
|
516
|
+
CONTENTFUL_SPACE_ID=your-space-id
|
|
517
|
+
CONTENTFUL_MANAGEMENT_TOKEN=your-management-token
|
|
518
|
+
CONTENTFUL_ENVIRONMENT_NAME=master
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### 2. Generate Types
|
|
522
|
+
|
|
523
|
+
```bash
|
|
524
|
+
pnpm --filter @se-studio/contentful-rest-api generate:types
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
This creates `src/generated/contentful-types.ts` with types matching your Contentful content model.
|
|
528
|
+
|
|
529
|
+
### 3. Use Generated Types
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
import type { TypePageSkeleton } from './generated/contentful-types';
|
|
533
|
+
import { contentfulEntryRest } from '@se-studio/contentful-rest-api';
|
|
534
|
+
|
|
535
|
+
const page = await client.getEntry<TypePageSkeleton>('entry-id');
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
## Configuration Options
|
|
539
|
+
|
|
540
|
+
### ContentfulConfig
|
|
541
|
+
|
|
542
|
+
```typescript
|
|
543
|
+
interface ContentfulConfig {
|
|
544
|
+
spaceId: string;
|
|
545
|
+
accessToken: string;
|
|
546
|
+
environment?: string; // defaults to 'master'
|
|
547
|
+
host?: string; // for proxies or custom endpoints
|
|
548
|
+
options?: Partial<CreateClientParams>;
|
|
549
|
+
}
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### FetchOptions
|
|
553
|
+
|
|
554
|
+
```typescript
|
|
555
|
+
interface FetchOptions {
|
|
556
|
+
locale?: string;
|
|
557
|
+
preview?: boolean;
|
|
558
|
+
include?: number; // include depth for linked entries (default: 10)
|
|
559
|
+
cache?: CacheConfig;
|
|
560
|
+
retry?: RetryConfig;
|
|
561
|
+
enrichPictureBlurPlaceholders?: boolean;
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
**Picture blur placeholders (`enrichPictureBlurPlaceholders`)** — When `true`, each included raster `IPicture` from Contentful (`*.ctfassets.net` image URLs) triggers an extra cached `fetch` of a tiny JPEG (width ~24px) to fill `blurDataURL` for `@se-studio/core-ui` / `next/image`. Skip with `false` or omit (default) to avoid those requests. Reuses the same asset cache tags as other asset enrichment so webhooks can still invalidate. Pictures that already define `blurDataURL` are left unchanged.
|
|
566
|
+
|
|
567
|
+
### CacheConfig
|
|
568
|
+
|
|
569
|
+
```typescript
|
|
570
|
+
interface CacheConfig {
|
|
571
|
+
tags?: string[]; // Next.js cache tags
|
|
572
|
+
revalidate?: number | false; // ISR revalidation time in seconds
|
|
573
|
+
cache?: 'force-cache' | 'no-store';
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Verbose logging
|
|
578
|
+
|
|
579
|
+
| Variable | Output |
|
|
580
|
+
|----------|--------|
|
|
581
|
+
| `LOG_CMS_QUERIES=1` | Structured query logs: operation, slug, payload size, URL (`[CMS query] {...}`) |
|
|
582
|
+
| `LOG_CMS_FETCH=1` | Raw Contentful URLs before each fetch (used by smoke tests) |
|
|
583
|
+
| `LOG_CMS=1` | Conversion/resolution diagnostics and revalidation traces |
|
|
584
|
+
|
|
585
|
+
Consolidate query logs with Next.js dev cache status:
|
|
586
|
+
|
|
587
|
+
```bash
|
|
588
|
+
pnpm dev 2>&1 | tee dev.log
|
|
589
|
+
pnpm --filter @se-studio/contentful-rest-api consolidate-cms-logs -- dev.log
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
Recommend `logging: { fetches: { fullUrl: true } }` in `next.config.js` so the consolidate script can match URLs reliably.
|
|
593
|
+
|
|
594
|
+
### RetryConfig
|
|
595
|
+
|
|
596
|
+
```typescript
|
|
597
|
+
interface RetryConfig {
|
|
598
|
+
maxRetries?: number; // default: 3
|
|
599
|
+
initialDelay?: number; // default: 1000ms
|
|
600
|
+
maxDelay?: number; // default: 30000ms
|
|
601
|
+
backoffMultiplier?: number; // default: 2
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### Primary Tag Selection
|
|
606
|
+
|
|
607
|
+
By default `getPrimaryTag` returns `tags[0]`. Pass a predicate to apply custom selection logic — the library does not prescribe which tag is "primary":
|
|
608
|
+
|
|
609
|
+
```typescript
|
|
610
|
+
import { getPrimaryTag, type PrimaryTagSelector } from '@se-studio/contentful-rest-api';
|
|
611
|
+
|
|
612
|
+
// Default: returns tags[0]
|
|
613
|
+
const primaryTag = getPrimaryTag(article);
|
|
614
|
+
|
|
615
|
+
// Custom selection — client supplies the predicate
|
|
616
|
+
const mySelector: PrimaryTagSelector = (tag, articleType) =>
|
|
617
|
+
articleType?.slug === 'news'
|
|
618
|
+
? tag.tagType?.slug === 'disease-area'
|
|
619
|
+
: tag.tagType?.slug === 'presentation-type';
|
|
620
|
+
|
|
621
|
+
const primaryTag = getPrimaryTag(article, mySelector);
|
|
622
|
+
|
|
623
|
+
// Also fix article.href URL generation via the converter context
|
|
624
|
+
const context = createBaseConverterContext({
|
|
625
|
+
...config,
|
|
626
|
+
primaryTagSelector: mySelector,
|
|
627
|
+
});
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
`ITagLink` carries `tagType?: { id, name, slug, show? }` so selectors can match on tag type without an extra fetch.
|
|
631
|
+
|
|
632
|
+
### Tag Visual Visibility
|
|
633
|
+
|
|
634
|
+
`show` on Tag and TagType controls **UI rendering only** (cards, detail pages). It does not affect search indexing (`indexed`), live pages (`hidden`), or related-articles matching.
|
|
635
|
+
|
|
636
|
+
```typescript
|
|
637
|
+
import {
|
|
638
|
+
filterVisibleTags,
|
|
639
|
+
isTagShowEnabled,
|
|
640
|
+
isTagVisible,
|
|
641
|
+
} from '@se-studio/contentful-rest-api';
|
|
642
|
+
|
|
643
|
+
// Visible when tag.show and tag.tagType.show are not explicitly false
|
|
644
|
+
const displayTags = filterVisibleTags(article.tags);
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
- `isTagShowEnabled(show)` — `undefined`/`null`/`true` => visible; only explicit `false` hides from UI
|
|
648
|
+
- `isTagVisible(tag)` — both tag and tag type must not be explicitly `false`
|
|
649
|
+
- `filterVisibleTags(tags)` — filter an article's tags for card/detail display
|
|
650
|
+
|
|
651
|
+
Link-only tag fetches include `fields.show` via `TAG_LINK_FIELDS` so visibility works on listings and cards.
|
|
652
|
+
|
|
653
|
+
## Next.js App Router Integration
|
|
654
|
+
|
|
655
|
+
Example usage in a Next.js Server Component:
|
|
656
|
+
|
|
657
|
+
```typescript
|
|
658
|
+
// app/[slug]/page.tsx
|
|
659
|
+
import { contentfulPageRest } from '@se-studio/contentful-rest-api';
|
|
660
|
+
|
|
661
|
+
interface PageProps {
|
|
662
|
+
params: { slug: string };
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
export default async function Page({ params }: PageProps) {
|
|
666
|
+
const page = await contentfulPageRest(
|
|
667
|
+
{
|
|
668
|
+
spaceId: process.env.CONTENTFUL_SPACE_ID!,
|
|
669
|
+
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,
|
|
670
|
+
},
|
|
671
|
+
params.slug,
|
|
672
|
+
{
|
|
673
|
+
cache: {
|
|
674
|
+
tags: [`page:${params.slug}`],
|
|
675
|
+
revalidate: 3600
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
);
|
|
679
|
+
|
|
680
|
+
if (!page) {
|
|
681
|
+
notFound();
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
return (
|
|
685
|
+
<div>
|
|
686
|
+
<h1>{page.title}</h1>
|
|
687
|
+
<p>{page.description}</p>
|
|
688
|
+
</div>
|
|
689
|
+
);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
export async function generateStaticParams() {
|
|
693
|
+
const pages = await contentfulAllPagesRest({
|
|
694
|
+
spaceId: process.env.CONTENTFUL_SPACE_ID!,
|
|
695
|
+
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
return pages.map((page) => ({
|
|
699
|
+
slug: page.slug,
|
|
700
|
+
}));
|
|
701
|
+
}
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
## API Reference
|
|
705
|
+
|
|
706
|
+
### Main Exports
|
|
707
|
+
|
|
708
|
+
#### API Functions
|
|
709
|
+
- **`contentfulPageRest`** - Fetches a page from Contentful by slug; if none exists, resolves a **page variant** (merged onto `originalPage` with `alternativeContents` swaps) for the same slug. Each `alternatePageContent` entry swaps `sourceContent` for **`replacementContents`** (array, supports 1→N); falls back to singular **`replacementContent`** when the array is empty.
|
|
710
|
+
- **`contentfulArticleRest`** - Fetches an article by slug and article type slug
|
|
711
|
+
- **`contentfulArticleTypeRest`** - Fetches an article type by slug
|
|
712
|
+
- **`contentfulAllPagesRest`** - Fetches all pages from Contentful
|
|
713
|
+
- **`contentfulAllPageLinks`** - Fetches all page links plus **page variant** links (metadata only), deduped by slug (page wins)
|
|
714
|
+
- **`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`.
|
|
715
|
+
- **`filterRelatedArticles`** - Filters and ranks article links (used by Related Articles collections *and* full-list helpers). Supports:
|
|
716
|
+
- Article type (ids or `articleTypeSlugs`)
|
|
717
|
+
- Tags (ids or `tagSlugs`; OR match; more matches = higher rank; distinct counting)
|
|
718
|
+
- Tag types (`tagTypeIds` / `tagTypeSlugs`; hard filter)
|
|
719
|
+
- Authors (ids or `authorSlugs`; score boost by default; `strictAuthorMatch: true` turns it into a hard exclude — required for person-scoped News/Pubs lists)
|
|
720
|
+
- Date range (`before` / `after`), `excludeArticleIds`, `count` (undefined = return all), `allowUnindexed`
|
|
721
|
+
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.
|
|
722
|
+
- **`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`.
|
|
723
|
+
|
|
724
|
+
#### Client Functions
|
|
725
|
+
- **`createContentfulClient`** - Creates a Contentful Content Delivery API (CDA) client
|
|
726
|
+
- **`createContentfulPreviewClient`** - Creates a Contentful Content Preview API (CPA) client
|
|
727
|
+
- **`getContentfulClient`** - Gets the appropriate client based on preview mode
|
|
728
|
+
|
|
729
|
+
#### Converter Functions
|
|
730
|
+
- **`createBaseConverterContext`** - Creates base converter context with default resolvers
|
|
731
|
+
- **`basePageConverter`** - Base converter for pages
|
|
732
|
+
- **`baseArticleConverter`** - Base converter for articles (full content). Resolves `download` via `lookupDownloadAsset` and `urlCalculators.download`.
|
|
733
|
+
- **`baseArticleLinkConverter`** - Lightweight converter for article list/browse UIs. Returns `IContentfulArticleLink`. Resolves `subtitle`, `visuals`, `tags`, `date`, `author`, `description`, `summary` (rich text), `download`, and `featuredImage` without fetching full article content. `href` is the internal detail URL when the article has article-level body content (`topContent`, `content`, or `bottomContent` on the article entry); external-only articles (no article-level body content, with `externalLink`) use `externalLink` as `href`. `externalLink` is always preserved on the link object when set. Used internally by `contentfulAllArticleLinks`.
|
|
734
|
+
- **`baseComponentConverter`** - Base converter for components
|
|
735
|
+
- **`baseHtmlComponentConverter`** - Base converter for `htmlComponent` entries (`IBaseHtmlComponent`)
|
|
736
|
+
- **`baseCollectionConverter`** - Base converter for collections
|
|
737
|
+
|
|
738
|
+
#### Revalidation Functions
|
|
739
|
+
- **`revalidateTags`** - Revalidates multiple Next.js cache tags
|
|
740
|
+
- **`revalidateSingleTag`** - Revalidates a single cache tag
|
|
741
|
+
- **`createRevalidationHandler`** - Creates Next.js API route handler for webhook revalidation
|
|
742
|
+
- **`getCacheTags`** - Gets cache tags based on content type and preview mode
|
|
743
|
+
|
|
744
|
+
#### Error Types
|
|
745
|
+
- **`ContentfulError`** - Base error class for Contentful API errors
|
|
746
|
+
- **`RateLimitError`** - Error for rate limit exceeded
|
|
747
|
+
- **`EntryNotFoundError`** - Error for entry not found
|
|
748
|
+
- **`AuthenticationError`** - Error for authentication failures
|
|
749
|
+
- **`ValidationError`** - Error for validation failures
|
|
750
|
+
|
|
751
|
+
#### Utility Functions
|
|
752
|
+
- **`isRetryableError`** - Check if an error is retryable
|
|
753
|
+
- **`withRetry`** - Retry function with exponential backoff
|
|
754
|
+
- **`RateLimiter`** - Rate limiter for controlling request rates
|
|
755
|
+
|
|
756
|
+
For detailed JSDoc documentation on all exports, see the TypeScript declaration files (`.d.ts`) in the package.
|
|
757
|
+
|
|
758
|
+
## License
|
|
759
|
+
|
|
760
|
+
MIT
|
|
761
|
+
|
|
762
|
+
## Repository
|
|
763
|
+
|
|
764
|
+
https://github.com/Something-Else-Studio/se-core-product
|