From 4bf50514bf68df4637efa8a035a577fafcff6281 Mon Sep 17 00:00:00 2001 From: rasm-its Date: Wed, 12 Aug 2026 18:03:11 +0200 Subject: [PATCH] gate locale behind functional consent --- dist/exports/client.d.js | 11 ---- dist/exports/client.d.js.map | 1 - dist/exports/next-middleware.d.js | 9 ---- dist/exports/next-middleware.d.js.map | 1 - dist/exports/rsc.d.js | 9 ---- dist/exports/rsc.d.js.map | 1 - dist/exports/server.d.js | 16 ------ dist/exports/server.d.js.map | 1 - dist/globals/CookieSettings/fields.d.js | 7 --- dist/globals/CookieSettings/fields.d.js.map | 1 - dist/globals/CookieSettings/index.d.js | 6 --- dist/globals/CookieSettings/index.d.js.map | 1 - .../SiteIntegrations/fields/analytics.d.js | 6 --- .../fields/analytics.d.js.map | 1 - .../globals/SiteIntegrations/fields/smtp.d.js | 9 ---- .../SiteIntegrations/fields/smtp.d.js.map | 1 - .../SiteIntegrations/fields/storage.d.js | 10 ---- .../SiteIntegrations/fields/storage.d.js.map | 1 - .../SiteIntegrations/fields/turnstile.d.js | 10 ---- .../fields/turnstile.d.js.map | 1 - dist/globals/SiteIntegrations/index.d.js | 3 -- dist/globals/SiteIntegrations/index.d.js.map | 1 - dist/globals/SiteSettings/fields/general.d.js | 6 --- .../SiteSettings/fields/general.d.js.map | 1 - .../SiteSettings/fields/navigation.d.js | 3 -- .../SiteSettings/fields/navigation.d.js.map | 1 - dist/globals/SiteSettings/fields/theme.d.js | 9 ---- .../SiteSettings/fields/theme.d.js.map | 1 - dist/globals/SiteSettings/index.d.js | 3 -- dist/globals/SiteSettings/index.d.js.map | 1 - dist/index.d.js | 17 ------ dist/index.d.js.map | 1 - dist/modules/access/access.d.js | 3 -- dist/modules/access/access.d.js.map | 1 - dist/modules/access/index.d.js | 7 --- dist/modules/access/index.d.js.map | 1 - dist/modules/access/injectRoles.d.js | 9 ---- dist/modules/access/injectRoles.d.js.map | 1 - dist/modules/access/predicates.d.js | 3 -- dist/modules/access/predicates.d.js.map | 1 - dist/modules/access/rolesField.d.js | 8 --- dist/modules/access/rolesField.d.js.map | 1 - dist/modules/access/types.d.js | 12 ----- dist/modules/access/types.d.js.map | 1 - dist/modules/analytics/Analytics.d.js | 14 ----- dist/modules/analytics/Analytics.d.js.map | 1 - dist/modules/analytics/client.d.js | 3 -- dist/modules/analytics/client.d.js.map | 1 - .../modules/analytics/getAnalyticsConfig.d.js | 8 --- .../analytics/getAnalyticsConfig.d.js.map | 1 - dist/modules/analytics/index.d.js | 3 -- dist/modules/analytics/index.d.js.map | 1 - dist/modules/analytics/index.d.ts | 2 +- dist/modules/analytics/index.js | 2 - dist/modules/analytics/index.js.map | 2 +- dist/modules/analytics/types.d.js | 5 -- dist/modules/analytics/types.d.js.map | 1 - dist/modules/blocks/RenderBlocks.d.js | 21 -------- dist/modules/blocks/RenderBlocks.d.js.map | 1 - dist/modules/blocks/index.d.js | 3 -- dist/modules/blocks/index.d.js.map | 1 - dist/modules/blocks/types.d.js | 9 ---- dist/modules/blocks/types.d.js.map | 1 - dist/modules/consent/ConsentContext.d.js | 3 -- dist/modules/consent/ConsentContext.d.js.map | 1 - dist/modules/consent/CookieBanner.d.js | 6 --- dist/modules/consent/CookieBanner.d.js.map | 1 - dist/modules/consent/CookieButton.d.js | 12 ----- dist/modules/consent/CookieButton.d.js.map | 1 - dist/modules/consent/categories.d.js | 6 --- dist/modules/consent/categories.d.js.map | 1 - dist/modules/consent/client.d.js | 6 --- dist/modules/consent/client.d.js.map | 1 - dist/modules/consent/getConsentTexts.d.js | 3 -- dist/modules/consent/getConsentTexts.d.js.map | 1 - dist/modules/consent/googleConsent.d.js | 3 -- dist/modules/consent/googleConsent.d.js.map | 1 - dist/modules/consent/index.d.js | 6 --- dist/modules/consent/index.d.js.map | 1 - dist/modules/consent/storage.d.js | 3 -- dist/modules/consent/storage.d.js.map | 1 - dist/modules/consent/texts.d.js | 3 -- dist/modules/consent/texts.d.js.map | 1 - dist/modules/consent/useConsent.d.js | 3 -- dist/modules/consent/useConsent.d.js.map | 1 - dist/modules/consent/useConsent.d.ts | 2 +- dist/modules/consent/useConsent.js | 33 +++++++++++- dist/modules/consent/useConsent.js.map | 2 +- dist/modules/content/archiveFields.d.js | 12 ----- dist/modules/content/archiveFields.d.js.map | 1 - dist/modules/content/getArchiveEntries.d.js | 3 -- .../content/getArchiveEntries.d.js.map | 1 - dist/modules/content/index.d.js | 7 --- dist/modules/content/index.d.js.map | 1 - dist/modules/content/paths.d.js | 3 -- dist/modules/content/paths.d.js.map | 1 - dist/modules/content/resolveRoute.d.js | 3 -- dist/modules/content/resolveRoute.d.js.map | 1 - dist/modules/content/types.d.js | 15 ------ dist/modules/content/types.d.js.map | 1 - dist/modules/email/index.d.js | 3 -- dist/modules/email/index.d.js.map | 1 - dist/modules/email/panelSmtpAdapter.d.js | 23 -------- dist/modules/email/panelSmtpAdapter.d.js.map | 1 - dist/modules/email/sendEmail.d.js | 3 -- dist/modules/email/sendEmail.d.js.map | 1 - dist/modules/forms/formsPluginConfig.d.js | 10 ---- dist/modules/forms/formsPluginConfig.d.js.map | 1 - dist/modules/forms/index.d.js | 6 --- dist/modules/forms/index.d.js.map | 1 - dist/modules/forms/rateLimit.d.js | 7 --- dist/modules/forms/rateLimit.d.js.map | 1 - dist/modules/forms/submitForm.d.js | 3 -- dist/modules/forms/submitForm.d.js.map | 1 - dist/modules/forms/types.d.js | 6 --- dist/modules/forms/types.d.js.map | 1 - dist/modules/forms/validateSubmission.d.js | 3 -- .../modules/forms/validateSubmission.d.js.map | 1 - .../frontend/createContentHelpers.d.js | 3 -- .../frontend/createContentHelpers.d.js.map | 1 - dist/modules/frontend/index.d.js | 3 -- dist/modules/frontend/index.d.js.map | 1 - dist/modules/i18n/getLocalizedSlugs.d.js | 3 -- dist/modules/i18n/getLocalizedSlugs.d.js.map | 1 - dist/modules/i18n/helpers.d.js | 5 -- dist/modules/i18n/helpers.d.js.map | 1 - dist/modules/i18n/index.d.js | 9 ---- dist/modules/i18n/index.d.js.map | 1 - dist/modules/i18n/localeMiddleware.d.js | 3 -- dist/modules/i18n/localeMiddleware.d.js.map | 1 - dist/modules/i18n/localeMiddleware.d.ts | 28 +++++++--- dist/modules/i18n/localeMiddleware.js | 39 ++++++++++---- dist/modules/i18n/localeMiddleware.js.map | 2 +- dist/modules/i18n/localizationConfig.d.js | 3 -- dist/modules/i18n/localizationConfig.d.js.map | 1 - dist/modules/i18n/localizedPath.d.js | 3 -- dist/modules/i18n/localizedPath.d.js.map | 1 - dist/modules/i18n/negotiateLocale.d.js | 3 -- dist/modules/i18n/negotiateLocale.d.js.map | 1 - dist/modules/i18n/types.d.js | 7 --- dist/modules/i18n/types.d.js.map | 1 - dist/modules/i18n/validation.d.js | 6 --- dist/modules/i18n/validation.d.js.map | 1 - dist/modules/pages/getSystemPagePath.d.js | 3 -- dist/modules/pages/getSystemPagePath.d.js.map | 1 - dist/modules/pages/index.d.js | 5 -- dist/modules/pages/index.d.js.map | 1 - dist/modules/pages/systemPagesFields.d.js | 11 ---- dist/modules/pages/systemPagesFields.d.js.map | 1 - dist/modules/pages/systemPagesFields.js | 6 ++- dist/modules/pages/systemPagesFields.js.map | 2 +- dist/modules/pages/types.d.js | 13 ----- dist/modules/pages/types.d.js.map | 1 - dist/modules/pages/types.d.ts | 2 +- dist/modules/pages/types.js | 3 +- dist/modules/pages/types.js.map | 2 +- dist/modules/payload/getGlobal.d.js | 8 --- dist/modules/payload/getGlobal.d.js.map | 1 - dist/modules/payload/getSiteIntegrations.d.js | 18 ------- .../payload/getSiteIntegrations.d.js.map | 1 - dist/modules/payload/getSiteSettings.d.js | 12 ----- dist/modules/payload/getSiteSettings.d.js.map | 1 - dist/modules/payload/index.d.js | 5 -- dist/modules/payload/index.d.js.map | 1 - dist/modules/seo/autoFillMeta.d.js | 11 ---- dist/modules/seo/autoFillMeta.d.js.map | 1 - dist/modules/seo/buildMetadata.d.js | 3 -- dist/modules/seo/buildMetadata.d.js.map | 1 - dist/modules/seo/buildRobots.d.js | 3 -- dist/modules/seo/buildRobots.d.js.map | 1 - dist/modules/seo/buildSitemapEntries.d.js | 3 -- dist/modules/seo/buildSitemapEntries.d.js.map | 1 - dist/modules/seo/composeTitle.d.js | 3 -- dist/modules/seo/composeTitle.d.js.map | 1 - dist/modules/seo/createMetadataGenerator.d.js | 3 -- .../seo/createMetadataGenerator.d.js.map | 1 - dist/modules/seo/createPageMetadata.d.js | 3 -- dist/modules/seo/createPageMetadata.d.js.map | 1 - dist/modules/seo/hreflang.d.js | 3 -- dist/modules/seo/hreflang.d.js.map | 1 - dist/modules/seo/index.d.js | 15 ------ dist/modules/seo/index.d.js.map | 1 - dist/modules/seo/injectAutoFillMeta.d.js | 10 ---- dist/modules/seo/injectAutoFillMeta.d.js.map | 1 - dist/modules/seo/injectSeoTabs.d.js | 16 ------ dist/modules/seo/injectSeoTabs.d.js.map | 1 - dist/modules/seo/readSiteMetaConfig.d.js | 10 ---- dist/modules/seo/readSiteMetaConfig.d.js.map | 1 - dist/modules/seo/seoPluginConfig.d.js | 3 -- dist/modules/seo/seoPluginConfig.d.js.map | 1 - dist/modules/seo/slugsAcrossLocales.d.js | 12 ----- dist/modules/seo/slugsAcrossLocales.d.js.map | 1 - dist/modules/seo/types.d.js | 7 --- dist/modules/seo/types.d.js.map | 1 - dist/modules/slug/buildSlugField.d.js | 3 -- dist/modules/slug/buildSlugField.d.js.map | 1 - dist/modules/slug/index.d.js | 3 -- dist/modules/slug/index.d.js.map | 1 - dist/modules/turnstile/Turnstile.d.js | 12 ----- dist/modules/turnstile/Turnstile.d.js.map | 1 - dist/modules/turnstile/client.d.js | 3 -- dist/modules/turnstile/client.d.js.map | 1 - dist/modules/turnstile/index.d.js | 3 -- dist/modules/turnstile/index.d.js.map | 1 - dist/modules/turnstile/verify.d.js | 3 -- dist/modules/turnstile/verify.d.js.map | 1 - dist/plugin.d.js | 25 --------- dist/plugin.d.js.map | 1 - dist/types.d.js | 6 --- dist/types.d.js.map | 1 - src/modules/consent/useConsent.ts | 54 +++++++++++++++---- src/modules/i18n/localeMiddleware.ts | 45 +++++++++++++--- 212 files changed, 173 insertions(+), 840 deletions(-) delete mode 100644 dist/exports/client.d.js delete mode 100644 dist/exports/client.d.js.map delete mode 100644 dist/exports/next-middleware.d.js delete mode 100644 dist/exports/next-middleware.d.js.map delete mode 100644 dist/exports/rsc.d.js delete mode 100644 dist/exports/rsc.d.js.map delete mode 100644 dist/exports/server.d.js delete mode 100644 dist/exports/server.d.js.map delete mode 100644 dist/globals/CookieSettings/fields.d.js delete mode 100644 dist/globals/CookieSettings/fields.d.js.map delete mode 100644 dist/globals/CookieSettings/index.d.js delete mode 100644 dist/globals/CookieSettings/index.d.js.map delete mode 100644 dist/globals/SiteIntegrations/fields/analytics.d.js delete mode 100644 dist/globals/SiteIntegrations/fields/analytics.d.js.map delete mode 100644 dist/globals/SiteIntegrations/fields/smtp.d.js delete mode 100644 dist/globals/SiteIntegrations/fields/smtp.d.js.map delete mode 100644 dist/globals/SiteIntegrations/fields/storage.d.js delete mode 100644 dist/globals/SiteIntegrations/fields/storage.d.js.map delete mode 100644 dist/globals/SiteIntegrations/fields/turnstile.d.js delete mode 100644 dist/globals/SiteIntegrations/fields/turnstile.d.js.map delete mode 100644 dist/globals/SiteIntegrations/index.d.js delete mode 100644 dist/globals/SiteIntegrations/index.d.js.map delete mode 100644 dist/globals/SiteSettings/fields/general.d.js delete mode 100644 dist/globals/SiteSettings/fields/general.d.js.map delete mode 100644 dist/globals/SiteSettings/fields/navigation.d.js delete mode 100644 dist/globals/SiteSettings/fields/navigation.d.js.map delete mode 100644 dist/globals/SiteSettings/fields/theme.d.js delete mode 100644 dist/globals/SiteSettings/fields/theme.d.js.map delete mode 100644 dist/globals/SiteSettings/index.d.js delete mode 100644 dist/globals/SiteSettings/index.d.js.map delete mode 100644 dist/index.d.js delete mode 100644 dist/index.d.js.map delete mode 100644 dist/modules/access/access.d.js delete mode 100644 dist/modules/access/access.d.js.map delete mode 100644 dist/modules/access/index.d.js delete mode 100644 dist/modules/access/index.d.js.map delete mode 100644 dist/modules/access/injectRoles.d.js delete mode 100644 dist/modules/access/injectRoles.d.js.map delete mode 100644 dist/modules/access/predicates.d.js delete mode 100644 dist/modules/access/predicates.d.js.map delete mode 100644 dist/modules/access/rolesField.d.js delete mode 100644 dist/modules/access/rolesField.d.js.map delete mode 100644 dist/modules/access/types.d.js delete mode 100644 dist/modules/access/types.d.js.map delete mode 100644 dist/modules/analytics/Analytics.d.js delete mode 100644 dist/modules/analytics/Analytics.d.js.map delete mode 100644 dist/modules/analytics/client.d.js delete mode 100644 dist/modules/analytics/client.d.js.map delete mode 100644 dist/modules/analytics/getAnalyticsConfig.d.js delete mode 100644 dist/modules/analytics/getAnalyticsConfig.d.js.map delete mode 100644 dist/modules/analytics/index.d.js delete mode 100644 dist/modules/analytics/index.d.js.map delete mode 100644 dist/modules/analytics/types.d.js delete mode 100644 dist/modules/analytics/types.d.js.map delete mode 100644 dist/modules/blocks/RenderBlocks.d.js delete mode 100644 dist/modules/blocks/RenderBlocks.d.js.map delete mode 100644 dist/modules/blocks/index.d.js delete mode 100644 dist/modules/blocks/index.d.js.map delete mode 100644 dist/modules/blocks/types.d.js delete mode 100644 dist/modules/blocks/types.d.js.map delete mode 100644 dist/modules/consent/ConsentContext.d.js delete mode 100644 dist/modules/consent/ConsentContext.d.js.map delete mode 100644 dist/modules/consent/CookieBanner.d.js delete mode 100644 dist/modules/consent/CookieBanner.d.js.map delete mode 100644 dist/modules/consent/CookieButton.d.js delete mode 100644 dist/modules/consent/CookieButton.d.js.map delete mode 100644 dist/modules/consent/categories.d.js delete mode 100644 dist/modules/consent/categories.d.js.map delete mode 100644 dist/modules/consent/client.d.js delete mode 100644 dist/modules/consent/client.d.js.map delete mode 100644 dist/modules/consent/getConsentTexts.d.js delete mode 100644 dist/modules/consent/getConsentTexts.d.js.map delete mode 100644 dist/modules/consent/googleConsent.d.js delete mode 100644 dist/modules/consent/googleConsent.d.js.map delete mode 100644 dist/modules/consent/index.d.js delete mode 100644 dist/modules/consent/index.d.js.map delete mode 100644 dist/modules/consent/storage.d.js delete mode 100644 dist/modules/consent/storage.d.js.map delete mode 100644 dist/modules/consent/texts.d.js delete mode 100644 dist/modules/consent/texts.d.js.map delete mode 100644 dist/modules/consent/useConsent.d.js delete mode 100644 dist/modules/consent/useConsent.d.js.map delete mode 100644 dist/modules/content/archiveFields.d.js delete mode 100644 dist/modules/content/archiveFields.d.js.map delete mode 100644 dist/modules/content/getArchiveEntries.d.js delete mode 100644 dist/modules/content/getArchiveEntries.d.js.map delete mode 100644 dist/modules/content/index.d.js delete mode 100644 dist/modules/content/index.d.js.map delete mode 100644 dist/modules/content/paths.d.js delete mode 100644 dist/modules/content/paths.d.js.map delete mode 100644 dist/modules/content/resolveRoute.d.js delete mode 100644 dist/modules/content/resolveRoute.d.js.map delete mode 100644 dist/modules/content/types.d.js delete mode 100644 dist/modules/content/types.d.js.map delete mode 100644 dist/modules/email/index.d.js delete mode 100644 dist/modules/email/index.d.js.map delete mode 100644 dist/modules/email/panelSmtpAdapter.d.js delete mode 100644 dist/modules/email/panelSmtpAdapter.d.js.map delete mode 100644 dist/modules/email/sendEmail.d.js delete mode 100644 dist/modules/email/sendEmail.d.js.map delete mode 100644 dist/modules/forms/formsPluginConfig.d.js delete mode 100644 dist/modules/forms/formsPluginConfig.d.js.map delete mode 100644 dist/modules/forms/index.d.js delete mode 100644 dist/modules/forms/index.d.js.map delete mode 100644 dist/modules/forms/rateLimit.d.js delete mode 100644 dist/modules/forms/rateLimit.d.js.map delete mode 100644 dist/modules/forms/submitForm.d.js delete mode 100644 dist/modules/forms/submitForm.d.js.map delete mode 100644 dist/modules/forms/types.d.js delete mode 100644 dist/modules/forms/types.d.js.map delete mode 100644 dist/modules/forms/validateSubmission.d.js delete mode 100644 dist/modules/forms/validateSubmission.d.js.map delete mode 100644 dist/modules/frontend/createContentHelpers.d.js delete mode 100644 dist/modules/frontend/createContentHelpers.d.js.map delete mode 100644 dist/modules/frontend/index.d.js delete mode 100644 dist/modules/frontend/index.d.js.map delete mode 100644 dist/modules/i18n/getLocalizedSlugs.d.js delete mode 100644 dist/modules/i18n/getLocalizedSlugs.d.js.map delete mode 100644 dist/modules/i18n/helpers.d.js delete mode 100644 dist/modules/i18n/helpers.d.js.map delete mode 100644 dist/modules/i18n/index.d.js delete mode 100644 dist/modules/i18n/index.d.js.map delete mode 100644 dist/modules/i18n/localeMiddleware.d.js delete mode 100644 dist/modules/i18n/localeMiddleware.d.js.map delete mode 100644 dist/modules/i18n/localizationConfig.d.js delete mode 100644 dist/modules/i18n/localizationConfig.d.js.map delete mode 100644 dist/modules/i18n/localizedPath.d.js delete mode 100644 dist/modules/i18n/localizedPath.d.js.map delete mode 100644 dist/modules/i18n/negotiateLocale.d.js delete mode 100644 dist/modules/i18n/negotiateLocale.d.js.map delete mode 100644 dist/modules/i18n/types.d.js delete mode 100644 dist/modules/i18n/types.d.js.map delete mode 100644 dist/modules/i18n/validation.d.js delete mode 100644 dist/modules/i18n/validation.d.js.map delete mode 100644 dist/modules/pages/getSystemPagePath.d.js delete mode 100644 dist/modules/pages/getSystemPagePath.d.js.map delete mode 100644 dist/modules/pages/index.d.js delete mode 100644 dist/modules/pages/index.d.js.map delete mode 100644 dist/modules/pages/systemPagesFields.d.js delete mode 100644 dist/modules/pages/systemPagesFields.d.js.map delete mode 100644 dist/modules/pages/types.d.js delete mode 100644 dist/modules/pages/types.d.js.map delete mode 100644 dist/modules/payload/getGlobal.d.js delete mode 100644 dist/modules/payload/getGlobal.d.js.map delete mode 100644 dist/modules/payload/getSiteIntegrations.d.js delete mode 100644 dist/modules/payload/getSiteIntegrations.d.js.map delete mode 100644 dist/modules/payload/getSiteSettings.d.js delete mode 100644 dist/modules/payload/getSiteSettings.d.js.map delete mode 100644 dist/modules/payload/index.d.js delete mode 100644 dist/modules/payload/index.d.js.map delete mode 100644 dist/modules/seo/autoFillMeta.d.js delete mode 100644 dist/modules/seo/autoFillMeta.d.js.map delete mode 100644 dist/modules/seo/buildMetadata.d.js delete mode 100644 dist/modules/seo/buildMetadata.d.js.map delete mode 100644 dist/modules/seo/buildRobots.d.js delete mode 100644 dist/modules/seo/buildRobots.d.js.map delete mode 100644 dist/modules/seo/buildSitemapEntries.d.js delete mode 100644 dist/modules/seo/buildSitemapEntries.d.js.map delete mode 100644 dist/modules/seo/composeTitle.d.js delete mode 100644 dist/modules/seo/composeTitle.d.js.map delete mode 100644 dist/modules/seo/createMetadataGenerator.d.js delete mode 100644 dist/modules/seo/createMetadataGenerator.d.js.map delete mode 100644 dist/modules/seo/createPageMetadata.d.js delete mode 100644 dist/modules/seo/createPageMetadata.d.js.map delete mode 100644 dist/modules/seo/hreflang.d.js delete mode 100644 dist/modules/seo/hreflang.d.js.map delete mode 100644 dist/modules/seo/index.d.js delete mode 100644 dist/modules/seo/index.d.js.map delete mode 100644 dist/modules/seo/injectAutoFillMeta.d.js delete mode 100644 dist/modules/seo/injectAutoFillMeta.d.js.map delete mode 100644 dist/modules/seo/injectSeoTabs.d.js delete mode 100644 dist/modules/seo/injectSeoTabs.d.js.map delete mode 100644 dist/modules/seo/readSiteMetaConfig.d.js delete mode 100644 dist/modules/seo/readSiteMetaConfig.d.js.map delete mode 100644 dist/modules/seo/seoPluginConfig.d.js delete mode 100644 dist/modules/seo/seoPluginConfig.d.js.map delete mode 100644 dist/modules/seo/slugsAcrossLocales.d.js delete mode 100644 dist/modules/seo/slugsAcrossLocales.d.js.map delete mode 100644 dist/modules/seo/types.d.js delete mode 100644 dist/modules/seo/types.d.js.map delete mode 100644 dist/modules/slug/buildSlugField.d.js delete mode 100644 dist/modules/slug/buildSlugField.d.js.map delete mode 100644 dist/modules/slug/index.d.js delete mode 100644 dist/modules/slug/index.d.js.map delete mode 100644 dist/modules/turnstile/Turnstile.d.js delete mode 100644 dist/modules/turnstile/Turnstile.d.js.map delete mode 100644 dist/modules/turnstile/client.d.js delete mode 100644 dist/modules/turnstile/client.d.js.map delete mode 100644 dist/modules/turnstile/index.d.js delete mode 100644 dist/modules/turnstile/index.d.js.map delete mode 100644 dist/modules/turnstile/verify.d.js delete mode 100644 dist/modules/turnstile/verify.d.js.map delete mode 100644 dist/plugin.d.js delete mode 100644 dist/plugin.d.js.map delete mode 100644 dist/types.d.js delete mode 100644 dist/types.d.js.map diff --git a/dist/exports/client.d.js b/dist/exports/client.d.js deleted file mode 100644 index 5ee75d0..0000000 --- a/dist/exports/client.d.js +++ /dev/null @@ -1,11 +0,0 @@ -export { Analytics } from '../modules/analytics/client.js'; -/** - * Entry point: ipal-kit/client - * - * Client-side ('use client') exports — React hooks, providers, and UI - * components. Kept separate from the main entry so server bundles don't pull in - * client-only code. - */ export { ConsentProvider, CookieBanner, CookieButton, useConsent, useConsentContext } from '../modules/consent/client.js'; -export { Turnstile } from '../modules/turnstile/client.js'; - -//# sourceMappingURL=client.d.js.map \ No newline at end of file diff --git a/dist/exports/client.d.js.map b/dist/exports/client.d.js.map deleted file mode 100644 index ebf6360..0000000 --- a/dist/exports/client.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["client.d.ts"],"sourcesContent":["export { Analytics } from '../modules/analytics/client.js';\n/**\n * Entry point: ipal-kit/client\n *\n * Client-side ('use client') exports — React hooks, providers, and UI\n * components. Kept separate from the main entry so server bundles don't pull in\n * client-only code.\n */\nexport { ConsentProvider, CookieBanner, CookieButton, useConsent, useConsentContext, } from '../modules/consent/client.js';\nexport type { CookieBannerClassNames } from '../modules/consent/client.js';\nexport { Turnstile } from '../modules/turnstile/client.js';\nexport type { TurnstileProps } from '../modules/turnstile/client.js';\n"],"names":["Analytics","ConsentProvider","CookieBanner","CookieButton","useConsent","useConsentContext","Turnstile"],"mappings":"AAAA,SAASA,SAAS,QAAQ,iCAAiC;AAC3D;;;;;;CAMC,GACD,SAASC,eAAe,EAAEC,YAAY,EAAEC,YAAY,EAAEC,UAAU,EAAEC,iBAAiB,QAAS,+BAA+B;AAE3H,SAASC,SAAS,QAAQ,iCAAiC"} \ No newline at end of file diff --git a/dist/exports/next-middleware.d.js b/dist/exports/next-middleware.d.js deleted file mode 100644 index 09d9c77..0000000 --- a/dist/exports/next-middleware.d.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Entry point: ipal-kit/next/middleware - * - * Re-exports the locale middleware factory and default matcher for use in a - * client project's middleware.ts. Kept as a thin re-export so the Next-facing - * surface is separate from the main package export. - */ export { createLocaleMiddleware, DEFAULT_MIDDLEWARE_MATCHER } from '../modules/i18n/index.js'; - -//# sourceMappingURL=next-middleware.d.js.map \ No newline at end of file diff --git a/dist/exports/next-middleware.d.js.map b/dist/exports/next-middleware.d.js.map deleted file mode 100644 index 201ef1c..0000000 --- a/dist/exports/next-middleware.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["next-middleware.d.ts"],"sourcesContent":["/**\n * Entry point: ipal-kit/next/middleware\n *\n * Re-exports the locale middleware factory and default matcher for use in a\n * client project's middleware.ts. Kept as a thin re-export so the Next-facing\n * surface is separate from the main package export.\n */\nexport { createLocaleMiddleware, DEFAULT_MIDDLEWARE_MATCHER } from '../modules/i18n/index.js';\nexport type { LocaleMiddlewareResult } from '../modules/i18n/index.js';\n"],"names":["createLocaleMiddleware","DEFAULT_MIDDLEWARE_MATCHER"],"mappings":"AAAA;;;;;;CAMC,GACD,SAASA,sBAAsB,EAAEC,0BAA0B,QAAQ,2BAA2B"} \ No newline at end of file diff --git a/dist/exports/rsc.d.js b/dist/exports/rsc.d.js deleted file mode 100644 index 941f5c2..0000000 --- a/dist/exports/rsc.d.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Entry point: ipal-kit/rsc - * - * Server-component exports. RenderBlocks is a React Server Component, so it - * lives here rather than in the main package entry to keep React out of the - * server-config bundle. - */ export { RenderBlocks } from '../modules/blocks/index.js'; - -//# sourceMappingURL=rsc.d.js.map \ No newline at end of file diff --git a/dist/exports/rsc.d.js.map b/dist/exports/rsc.d.js.map deleted file mode 100644 index 599e87f..0000000 --- a/dist/exports/rsc.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["rsc.d.ts"],"sourcesContent":["/**\n * Entry point: ipal-kit/rsc\n *\n * Server-component exports. RenderBlocks is a React Server Component, so it\n * lives here rather than in the main package entry to keep React out of the\n * server-config bundle.\n */\nexport { RenderBlocks } from '../modules/blocks/index.js';\nexport type { BlockComponentMap, BlockData, EnhanceProps, RenderBlocksProps, } from '../modules/blocks/index.js';\n"],"names":["RenderBlocks"],"mappings":"AAAA;;;;;;CAMC,GACD,SAASA,YAAY,QAAQ,6BAA6B"} \ No newline at end of file diff --git a/dist/exports/server.d.js b/dist/exports/server.d.js deleted file mode 100644 index 9abe2fa..0000000 --- a/dist/exports/server.d.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Entry point: ipal-kit/server - * - * Server-only runtime functions — these import 'server-only' (Turnstile secret, - * SMTP password, nodemailer). Kept OUT of the main entry so that loading the - * Payload config or running `payload generate:importmap` (both Node scripts, - * no bundler) never pulls in 'server-only', which throws outside a bundled - * server context. - * - * Import these only from Server Actions, route handlers, or server components — - * never from the Payload config or client code. - */ export { verifyTurnstile } from '../modules/turnstile/index.js'; -export { sendEmail } from '../modules/email/index.js'; -export { submitForm } from '../modules/forms/index.js'; - -//# sourceMappingURL=server.d.js.map \ No newline at end of file diff --git a/dist/exports/server.d.js.map b/dist/exports/server.d.js.map deleted file mode 100644 index 9f7548a..0000000 --- a/dist/exports/server.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["server.d.ts"],"sourcesContent":["/**\n * Entry point: ipal-kit/server\n *\n * Server-only runtime functions — these import 'server-only' (Turnstile secret,\n * SMTP password, nodemailer). Kept OUT of the main entry so that loading the\n * Payload config or running `payload generate:importmap` (both Node scripts,\n * no bundler) never pulls in 'server-only', which throws outside a bundled\n * server context.\n *\n * Import these only from Server Actions, route handlers, or server components —\n * never from the Payload config or client code.\n */\nexport { verifyTurnstile } from '../modules/turnstile/index.js';\nexport { sendEmail } from '../modules/email/index.js';\nexport type { SendEmailArgs, SendEmailResult } from '../modules/email/index.js';\nexport { submitForm } from '../modules/forms/index.js';\nexport type { SubmitFormArgs, SubmitFormResult } from '../modules/forms/index.js';\n"],"names":["verifyTurnstile","sendEmail","submitForm"],"mappings":"AAAA;;;;;;;;;;;CAWC,GACD,SAASA,eAAe,QAAQ,gCAAgC;AAChE,SAASC,SAAS,QAAQ,4BAA4B;AAEtD,SAASC,UAAU,QAAQ,4BAA4B"} \ No newline at end of file diff --git a/dist/globals/CookieSettings/fields.d.js b/dist/globals/CookieSettings/fields.d.js deleted file mode 100644 index d09e235..0000000 --- a/dist/globals/CookieSettings/fields.d.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Fields for the CookieSettings global — GDPR consent banner copy, editable - * per locale. The privacy-policy link is NOT stored here: it comes from the - * pages module (system page role 'privacyPolicy'), keeping one source of truth. - */ export { }; - -//# sourceMappingURL=fields.d.js.map \ No newline at end of file diff --git a/dist/globals/CookieSettings/fields.d.js.map b/dist/globals/CookieSettings/fields.d.js.map deleted file mode 100644 index fd60b80..0000000 --- a/dist/globals/CookieSettings/fields.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["fields.d.ts"],"sourcesContent":["import type { Field } from 'payload';\n/**\n * Fields for the CookieSettings global — GDPR consent banner copy, editable\n * per locale. The privacy-policy link is NOT stored here: it comes from the\n * pages module (system page role 'privacyPolicy'), keeping one source of truth.\n */\nexport declare const cookieSettingsFields: Field[];\n"],"names":[],"mappings":"AACA;;;;CAIC,GACD,WAAmD"} \ No newline at end of file diff --git a/dist/globals/CookieSettings/index.d.js b/dist/globals/CookieSettings/index.d.js deleted file mode 100644 index 16e2ac6..0000000 --- a/dist/globals/CookieSettings/index.d.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Builds the CookieSettings global — consent banner copy managed by editors. - * Public read (the banner needs it on the frontend for anonymous visitors). - */ export { }; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/globals/CookieSettings/index.d.js.map b/dist/globals/CookieSettings/index.d.js.map deleted file mode 100644 index 05454af..0000000 --- a/dist/globals/CookieSettings/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["import type { GlobalConfig } from 'payload';\n/**\n * Builds the CookieSettings global — consent banner copy managed by editors.\n * Public read (the banner needs it on the frontend for anonymous visitors).\n */\nexport declare function buildCookieSettings(): GlobalConfig;\n"],"names":[],"mappings":"AACA;;;CAGC,GACD,WAA4D"} \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/fields/analytics.d.js b/dist/globals/SiteIntegrations/fields/analytics.d.js deleted file mode 100644 index 42dd76d..0000000 --- a/dist/globals/SiteIntegrations/fields/analytics.d.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Analytics configuration — GA4 measurement ID and GTM container ID. - * IDs are public (exposed client-side), so no read restriction needed. - */ export { }; - -//# sourceMappingURL=analytics.d.js.map \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/fields/analytics.d.js.map b/dist/globals/SiteIntegrations/fields/analytics.d.js.map deleted file mode 100644 index 56fc1d2..0000000 --- a/dist/globals/SiteIntegrations/fields/analytics.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["analytics.d.ts"],"sourcesContent":["import type { Field } from 'payload';\n/**\n * Analytics configuration — GA4 measurement ID and GTM container ID.\n * IDs are public (exposed client-side), so no read restriction needed.\n */\nexport declare const analyticsFields: Field[];\n"],"names":[],"mappings":"AACA;;;CAGC,GACD,WAA8C"} \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/fields/smtp.d.js b/dist/globals/SiteIntegrations/fields/smtp.d.js deleted file mode 100644 index 91a5a66..0000000 --- a/dist/globals/SiteIntegrations/fields/smtp.d.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * SMTP transport settings for outbound email. - * - * Protected at the global level (SiteIntegrations requires an authenticated - * user), so all fields — including the password — stay editable in the admin - * panel while remaining inaccessible to anonymous API requests. - */ export { }; - -//# sourceMappingURL=smtp.d.js.map \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/fields/smtp.d.js.map b/dist/globals/SiteIntegrations/fields/smtp.d.js.map deleted file mode 100644 index 8086312..0000000 --- a/dist/globals/SiteIntegrations/fields/smtp.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["smtp.d.ts"],"sourcesContent":["import type { Field } from 'payload';\n/**\n * SMTP transport settings for outbound email.\n *\n * Protected at the global level (SiteIntegrations requires an authenticated\n * user), so all fields — including the password — stay editable in the admin\n * panel while remaining inaccessible to anonymous API requests.\n */\nexport declare const smtpFields: Field[];\n"],"names":[],"mappings":"AACA;;;;;;CAMC,GACD,WAAyC"} \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/fields/storage.d.js b/dist/globals/SiteIntegrations/fields/storage.d.js deleted file mode 100644 index cc2d714..0000000 --- a/dist/globals/SiteIntegrations/fields/storage.d.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Cloudflare R2 storage credentials. - * Reserved for future use — media offloading to R2. - * - * Protected at the global level (SiteIntegrations requires an authenticated - * user), so the access keys stay editable in the admin panel while remaining - * inaccessible to anonymous API requests. - */ export { }; - -//# sourceMappingURL=storage.d.js.map \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/fields/storage.d.js.map b/dist/globals/SiteIntegrations/fields/storage.d.js.map deleted file mode 100644 index fdd4b73..0000000 --- a/dist/globals/SiteIntegrations/fields/storage.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["storage.d.ts"],"sourcesContent":["import type { Field } from 'payload';\n/**\n * Cloudflare R2 storage credentials.\n * Reserved for future use — media offloading to R2.\n *\n * Protected at the global level (SiteIntegrations requires an authenticated\n * user), so the access keys stay editable in the admin panel while remaining\n * inaccessible to anonymous API requests.\n */\nexport declare const storageFields: Field[];\n"],"names":[],"mappings":"AACA;;;;;;;CAOC,GACD,WAA4C"} \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/fields/turnstile.d.js b/dist/globals/SiteIntegrations/fields/turnstile.d.js deleted file mode 100644 index 0bcd357..0000000 --- a/dist/globals/SiteIntegrations/fields/turnstile.d.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Cloudflare Turnstile credentials. - * - * siteKey is public (rendered in the widget); secretKey is used for - * server-side verification. Both are protected at the global level - * (SiteIntegrations requires an authenticated user) rather than per-field, - * so they remain editable in the admin panel. - */ export { }; - -//# sourceMappingURL=turnstile.d.js.map \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/fields/turnstile.d.js.map b/dist/globals/SiteIntegrations/fields/turnstile.d.js.map deleted file mode 100644 index d07dd13..0000000 --- a/dist/globals/SiteIntegrations/fields/turnstile.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["turnstile.d.ts"],"sourcesContent":["import type { Field } from 'payload';\n/**\n * Cloudflare Turnstile credentials.\n *\n * siteKey is public (rendered in the widget); secretKey is used for\n * server-side verification. Both are protected at the global level\n * (SiteIntegrations requires an authenticated user) rather than per-field,\n * so they remain editable in the admin panel.\n */\nexport declare const turnstileFields: Field[];\n"],"names":[],"mappings":"AACA;;;;;;;CAOC,GACD,WAA8C"} \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/index.d.js b/dist/globals/SiteIntegrations/index.d.js deleted file mode 100644 index c6f029b..0000000 --- a/dist/globals/SiteIntegrations/index.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/globals/SiteIntegrations/index.d.js.map b/dist/globals/SiteIntegrations/index.d.js.map deleted file mode 100644 index 5e58a5f..0000000 --- a/dist/globals/SiteIntegrations/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["import type { Field, GlobalConfig } from 'payload';\ntype BuildSiteIntegrationsArgs = {\n /** Extra fields injected by the client project */\n additionalFields?: Field[];\n};\n/**\n * Builds the SiteIntegrations global.\n *\n * Holds third-party service credentials. Access is enforced at the global\n * level — the whole global requires an authenticated user — so secrets stay\n * out of anonymous API responses while remaining editable in the admin panel\n * and readable via the server-side Local API. (Field-level read:false was\n * avoided because it also hides fields from the admin UI, making them\n * impossible to enter.)\n *\n * Unnamed tabs keep data flat (siteIntegrations.ga4MeasurementId).\n */\nexport declare function buildSiteIntegrations({ additionalFields, }?: BuildSiteIntegrationsArgs): GlobalConfig;\nexport {};\n"],"names":[],"mappings":"AAkBA,WAAU"} \ No newline at end of file diff --git a/dist/globals/SiteSettings/fields/general.d.js b/dist/globals/SiteSettings/fields/general.d.js deleted file mode 100644 index c6a08f4..0000000 --- a/dist/globals/SiteSettings/fields/general.d.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * General site identity fields. - * Consumed by SEO/OG (siteName, defaultShareImage) and frontend (logo). - */ export { }; - -//# sourceMappingURL=general.d.js.map \ No newline at end of file diff --git a/dist/globals/SiteSettings/fields/general.d.js.map b/dist/globals/SiteSettings/fields/general.d.js.map deleted file mode 100644 index 1c2bda9..0000000 --- a/dist/globals/SiteSettings/fields/general.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["general.d.ts"],"sourcesContent":["import type { Field } from 'payload';\n/**\n * General site identity fields.\n * Consumed by SEO/OG (siteName, defaultShareImage) and frontend (logo).\n */\nexport declare const generalFields: Field[];\n"],"names":[],"mappings":"AACA;;;CAGC,GACD,WAA4C"} \ No newline at end of file diff --git a/dist/globals/SiteSettings/fields/navigation.d.js b/dist/globals/SiteSettings/fields/navigation.d.js deleted file mode 100644 index 3b80b52..0000000 --- a/dist/globals/SiteSettings/fields/navigation.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=navigation.d.js.map \ No newline at end of file diff --git a/dist/globals/SiteSettings/fields/navigation.d.js.map b/dist/globals/SiteSettings/fields/navigation.d.js.map deleted file mode 100644 index dbcdd87..0000000 --- a/dist/globals/SiteSettings/fields/navigation.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["navigation.d.ts"],"sourcesContent":["export {};\n"],"names":[],"mappings":"AAAA,WAAU"} \ No newline at end of file diff --git a/dist/globals/SiteSettings/fields/theme.d.js b/dist/globals/SiteSettings/fields/theme.d.js deleted file mode 100644 index 80085bc..0000000 --- a/dist/globals/SiteSettings/fields/theme.d.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Theme behavior configuration. - * - * These are decisions, not visuals — the plugin stores them, the client - * template reads them and decides whether to render a toggle and which - * mode to start in. Appearance itself stays in the template. - */ export { }; - -//# sourceMappingURL=theme.d.js.map \ No newline at end of file diff --git a/dist/globals/SiteSettings/fields/theme.d.js.map b/dist/globals/SiteSettings/fields/theme.d.js.map deleted file mode 100644 index 4c53a79..0000000 --- a/dist/globals/SiteSettings/fields/theme.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["theme.d.ts"],"sourcesContent":["import type { Field } from 'payload';\n/**\n * Theme behavior configuration.\n *\n * These are decisions, not visuals — the plugin stores them, the client\n * template reads them and decides whether to render a toggle and which\n * mode to start in. Appearance itself stays in the template.\n */\nexport declare const themeFields: Field[];\n"],"names":[],"mappings":"AACA;;;;;;CAMC,GACD,WAA0C"} \ No newline at end of file diff --git a/dist/globals/SiteSettings/index.d.js b/dist/globals/SiteSettings/index.d.js deleted file mode 100644 index c6f029b..0000000 --- a/dist/globals/SiteSettings/index.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/globals/SiteSettings/index.d.js.map b/dist/globals/SiteSettings/index.d.js.map deleted file mode 100644 index 459a743..0000000 --- a/dist/globals/SiteSettings/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["import type { Field, GlobalConfig } from 'payload';\ntype BuildSiteSettingsArgs = {\n /** Extra fields injected by the client project */\n additionalFields?: Field[];\n /**\n * Fields for the \"System Pages\" tab — page assignments by role (homepage,\n * privacy policy, collection archives). Assembled by the caller, which is the\n * only place that knows which modules are enabled. The tab is omitted when\n * this is empty.\n */\n systemPageFields?: Field[];\n};\n/**\n * Builds the SiteSettings global.\n *\n * Composes tabs out of field groups; it deliberately doesn't know where those\n * groups come from. Earlier it imported the pages and content modules directly,\n * which meant a global — a presentation-layer concern — had an opinion about\n * blogs. Now the plugin's composition root passes fields in, and adding a new\n * kind of page assignment needs no change here.\n *\n * Uses unnamed tabs — data stays flat (siteSettings.siteName, not\n * siteSettings.general.siteName). Client-provided fields land in their own\n * \"Custom\" tab so core data paths never shift.\n */\nexport declare function buildSiteSettings({ additionalFields, systemPageFields, }?: BuildSiteSettingsArgs): GlobalConfig;\nexport {};\n"],"names":[],"mappings":"AA0BA,WAAU"} \ No newline at end of file diff --git a/dist/index.d.js b/dist/index.d.js deleted file mode 100644 index d859b15..0000000 --- a/dist/index.d.js +++ /dev/null @@ -1,17 +0,0 @@ -export { adminOnly, adminOnlyField, adminOrEditor, adminOrEditorField, adminOrSelf, authenticated, hasMinimumRole, isAdmin, isEditor, requireRole, requireRoleField, ROLE_HIERARCHY } from './modules/access/index.js'; -export { getAnalyticsConfig } from './modules/analytics/index.js'; -export { ACCEPT_ALL_CONSENT, CONSENT_CATEGORIES, CONSENT_COOKIE, CONSENT_MAX_AGE, CONSENT_VERSION, DEFAULT_CONSENT, getConsentTexts, parseConsent, REJECT_ALL_CONSENT, serializeConsent, setDefaultConsent, updateConsent } from './modules/consent/index.js'; -export { archiveFieldName, buildArchivePath, buildEntryPath, getArchiveEntries, parsePageParam, resolveRoute } from './modules/content/index.js'; -export { panelSmtpAdapter } from './modules/email/panelSmtpAdapter.js'; -export { buildFormsPlugin } from './modules/forms/formsPluginConfig.js'; -export { createContentHelpers } from './modules/frontend/index.js'; -export { buildLocalizedPath, getDefaultLocale, getLocaleCodes, getLocaleDefinition, getLocalizedSlugs, isValidLocale, LOCALE_COOKIE_NAME, matchAcceptLanguage, negotiateLocale, switchLocalePath } from './modules/i18n/index.js'; -export { createLocaleMiddleware, DEFAULT_MIDDLEWARE_MATCHER } from './modules/i18n/index.js'; -export { ALL_SYSTEM_PAGE_ROLES, getSystemPagePath } from './modules/pages/index.js'; -export { getGlobal, getSiteIntegrations, getSiteSettings, SITE_INTEGRATIONS_SLUG, SITE_SETTINGS_SLUG } from './modules/payload/index.js'; -export { buildHreflangAlternates, buildMetadata, composeTitle } from './modules/seo/index.js'; -export { buildAutoFillMetaHook, buildRobots, buildSitemapEntries, createMetadataGenerator, createPageMetadata, injectAutoFillMeta } from './modules/seo/index.js'; -export { buildSlugField, toSlug } from './modules/slug/index.js'; -export { ipalKit } from './plugin.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/index.d.js.map b/dist/index.d.js.map deleted file mode 100644 index 1986b00..0000000 --- a/dist/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export type { AccessOption, Role } from './modules/access/index.js';\nexport { adminOnly, adminOnlyField, adminOrEditor, adminOrEditorField, adminOrSelf, authenticated, hasMinimumRole, isAdmin, isEditor, requireRole, requireRoleField, ROLE_HIERARCHY, } from './modules/access/index.js';\nexport type { AnalyticsConfig } from './modules/analytics/index.js';\nexport { getAnalyticsConfig } from './modules/analytics/index.js';\nexport { ACCEPT_ALL_CONSENT, CONSENT_CATEGORIES, CONSENT_COOKIE, CONSENT_MAX_AGE, CONSENT_VERSION, DEFAULT_CONSENT, getConsentTexts, parseConsent, REJECT_ALL_CONSENT, serializeConsent, setDefaultConsent, updateConsent, } from './modules/consent/index.js';\nexport type { ConsentCategory, ConsentState, ConsentTexts } from './modules/consent/index.js';\nexport type { ContentCollectionOption, ContentOption, ResolvedRoute, } from './modules/content/index.js';\nexport { archiveFieldName, buildArchivePath, buildEntryPath, getArchiveEntries, parsePageParam, resolveRoute, } from './modules/content/index.js';\nexport type { ArchiveEntries } from './modules/content/index.js';\nexport { panelSmtpAdapter } from './modules/email/panelSmtpAdapter.js';\nexport type { PanelSmtpAdapterArgs } from './modules/email/panelSmtpAdapter.js';\nexport { buildFormsPlugin } from './modules/forms/formsPluginConfig.js';\nexport type { FormsCollectionOverrides, FormsFieldsOverride, FormsOption, } from './modules/forms/types.js';\nexport { createContentHelpers } from './modules/frontend/index.js';\nexport type { I18nConfig, LocaleDefinition, LocalizedSlugs } from './modules/i18n/index.js';\nexport { buildLocalizedPath, getDefaultLocale, getLocaleCodes, getLocaleDefinition, getLocalizedSlugs, isValidLocale, LOCALE_COOKIE_NAME, matchAcceptLanguage, negotiateLocale, switchLocalePath, } from './modules/i18n/index.js';\nexport type { LocaleMiddlewareResult } from './modules/i18n/index.js';\nexport { createLocaleMiddleware, DEFAULT_MIDDLEWARE_MATCHER } from './modules/i18n/index.js';\nexport type { PagesOption, SystemPageRole } from './modules/pages/index.js';\nexport { ALL_SYSTEM_PAGE_ROLES, getSystemPagePath } from './modules/pages/index.js';\nexport type { GlobalQueryOptions } from './modules/payload/index.js';\nexport { getGlobal, getSiteIntegrations, getSiteSettings, SITE_INTEGRATIONS_SLUG, SITE_SETTINGS_SLUG, } from './modules/payload/index.js';\nexport type { PageMetadata, SeoMeta, SeoOption } from './modules/seo/index.js';\nexport { buildHreflangAlternates, buildMetadata, composeTitle } from './modules/seo/index.js';\nexport type { AutoFillMapping, RobotsRules, SitemapEntry } from './modules/seo/index.js';\nexport { buildAutoFillMetaHook, buildRobots, buildSitemapEntries, createMetadataGenerator, createPageMetadata, injectAutoFillMeta, } from './modules/seo/index.js';\nexport { buildSlugField, toSlug } from './modules/slug/index.js';\nexport { ipalKit } from './plugin.js';\nexport type { IpalOptions } from './types.js';\n"],"names":["adminOnly","adminOnlyField","adminOrEditor","adminOrEditorField","adminOrSelf","authenticated","hasMinimumRole","isAdmin","isEditor","requireRole","requireRoleField","ROLE_HIERARCHY","getAnalyticsConfig","ACCEPT_ALL_CONSENT","CONSENT_CATEGORIES","CONSENT_COOKIE","CONSENT_MAX_AGE","CONSENT_VERSION","DEFAULT_CONSENT","getConsentTexts","parseConsent","REJECT_ALL_CONSENT","serializeConsent","setDefaultConsent","updateConsent","archiveFieldName","buildArchivePath","buildEntryPath","getArchiveEntries","parsePageParam","resolveRoute","panelSmtpAdapter","buildFormsPlugin","createContentHelpers","buildLocalizedPath","getDefaultLocale","getLocaleCodes","getLocaleDefinition","getLocalizedSlugs","isValidLocale","LOCALE_COOKIE_NAME","matchAcceptLanguage","negotiateLocale","switchLocalePath","createLocaleMiddleware","DEFAULT_MIDDLEWARE_MATCHER","ALL_SYSTEM_PAGE_ROLES","getSystemPagePath","getGlobal","getSiteIntegrations","getSiteSettings","SITE_INTEGRATIONS_SLUG","SITE_SETTINGS_SLUG","buildHreflangAlternates","buildMetadata","composeTitle","buildAutoFillMetaHook","buildRobots","buildSitemapEntries","createMetadataGenerator","createPageMetadata","injectAutoFillMeta","buildSlugField","toSlug","ipalKit"],"mappings":"AACA,SAASA,SAAS,EAAEC,cAAc,EAAEC,aAAa,EAAEC,kBAAkB,EAAEC,WAAW,EAAEC,aAAa,EAAEC,cAAc,EAAEC,OAAO,EAAEC,QAAQ,EAAEC,WAAW,EAAEC,gBAAgB,EAAEC,cAAc,QAAS,4BAA4B;AAExN,SAASC,kBAAkB,QAAQ,+BAA+B;AAClE,SAASC,kBAAkB,EAAEC,kBAAkB,EAAEC,cAAc,EAAEC,eAAe,EAAEC,eAAe,EAAEC,eAAe,EAAEC,eAAe,EAAEC,YAAY,EAAEC,kBAAkB,EAAEC,gBAAgB,EAAEC,iBAAiB,EAAEC,aAAa,QAAS,6BAA6B;AAG/P,SAASC,gBAAgB,EAAEC,gBAAgB,EAAEC,cAAc,EAAEC,iBAAiB,EAAEC,cAAc,EAAEC,YAAY,QAAS,6BAA6B;AAElJ,SAASC,gBAAgB,QAAQ,sCAAsC;AAEvE,SAASC,gBAAgB,QAAQ,uCAAuC;AAExE,SAASC,oBAAoB,QAAQ,8BAA8B;AAEnE,SAASC,kBAAkB,EAAEC,gBAAgB,EAAEC,cAAc,EAAEC,mBAAmB,EAAEC,iBAAiB,EAAEC,aAAa,EAAEC,kBAAkB,EAAEC,mBAAmB,EAAEC,eAAe,EAAEC,gBAAgB,QAAS,0BAA0B;AAEnO,SAASC,sBAAsB,EAAEC,0BAA0B,QAAQ,0BAA0B;AAE7F,SAASC,qBAAqB,EAAEC,iBAAiB,QAAQ,2BAA2B;AAEpF,SAASC,SAAS,EAAEC,mBAAmB,EAAEC,eAAe,EAAEC,sBAAsB,EAAEC,kBAAkB,QAAS,6BAA6B;AAE1I,SAASC,uBAAuB,EAAEC,aAAa,EAAEC,YAAY,QAAQ,yBAAyB;AAE9F,SAASC,qBAAqB,EAAEC,WAAW,EAAEC,mBAAmB,EAAEC,uBAAuB,EAAEC,kBAAkB,EAAEC,kBAAkB,QAAS,yBAAyB;AACnK,SAASC,cAAc,EAAEC,MAAM,QAAQ,0BAA0B;AACjE,SAASC,OAAO,QAAQ,cAAc"} \ No newline at end of file diff --git a/dist/modules/access/access.d.js b/dist/modules/access/access.d.js deleted file mode 100644 index 13cba76..0000000 --- a/dist/modules/access/access.d.js +++ /dev/null @@ -1,3 +0,0 @@ -/** Requires at least the given role, for field-level access. */ export { }; - -//# sourceMappingURL=access.d.js.map \ No newline at end of file diff --git a/dist/modules/access/access.d.js.map b/dist/modules/access/access.d.js.map deleted file mode 100644 index b4f313c..0000000 --- a/dist/modules/access/access.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["access.d.ts"],"sourcesContent":["import type { Access, FieldAccess } from 'payload';\nimport type { Role } from './types.js';\n/**\n * Collection-level access (returns boolean | Where).\n * Use in collection `access.read/create/update/delete`.\n */\nexport declare const adminOnly: Access;\nexport declare const adminOrEditor: Access;\nexport declare const authenticated: Access;\n/** Requires at least the given role. */\nexport declare const requireRole: (minimum: Role) => Access;\n/** Admins see all; others are constrained to their own document. */\nexport declare const adminOrSelf: Access;\n/**\n * Field-level access (returns boolean only — no Where support).\n * Use in field `access.read/update`.\n */\nexport declare const adminOnlyField: FieldAccess;\nexport declare const adminOrEditorField: FieldAccess;\n/** Requires at least the given role, for field-level access. */\nexport declare const requireRoleField: (minimum: Role) => FieldAccess;\n"],"names":[],"mappings":"AAmBA,8DAA8D,GAC9D,WAAsE"} \ No newline at end of file diff --git a/dist/modules/access/index.d.js b/dist/modules/access/index.d.js deleted file mode 100644 index a74c734..0000000 --- a/dist/modules/access/index.d.js +++ /dev/null @@ -1,7 +0,0 @@ -export { adminOnly, adminOnlyField, adminOrEditor, adminOrEditorField, adminOrSelf, authenticated, requireRole, requireRoleField } from './access.js'; -export { injectRoles } from './injectRoles.js'; -export { hasMinimumRole, isAdmin, isEditor } from './predicates.js'; -export { buildRolesField } from './rolesField.js'; -export { ROLE_HIERARCHY } from './types.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/access/index.d.js.map b/dist/modules/access/index.d.js.map deleted file mode 100644 index d36fa92..0000000 --- a/dist/modules/access/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { adminOnly, adminOnlyField, adminOrEditor, adminOrEditorField, adminOrSelf, authenticated, requireRole, requireRoleField, } from './access.js';\nexport { injectRoles } from './injectRoles.js';\nexport { hasMinimumRole, isAdmin, isEditor } from './predicates.js';\nexport { buildRolesField } from './rolesField.js';\nexport type { AccessOption, Role } from './types.js';\nexport { ROLE_HIERARCHY } from './types.js';\n"],"names":["adminOnly","adminOnlyField","adminOrEditor","adminOrEditorField","adminOrSelf","authenticated","requireRole","requireRoleField","injectRoles","hasMinimumRole","isAdmin","isEditor","buildRolesField","ROLE_HIERARCHY"],"mappings":"AAAA,SAASA,SAAS,EAAEC,cAAc,EAAEC,aAAa,EAAEC,kBAAkB,EAAEC,WAAW,EAAEC,aAAa,EAAEC,WAAW,EAAEC,gBAAgB,QAAS,cAAc;AACvJ,SAASC,WAAW,QAAQ,mBAAmB;AAC/C,SAASC,cAAc,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,kBAAkB;AACpE,SAASC,eAAe,QAAQ,kBAAkB;AAElD,SAASC,cAAc,QAAQ,aAAa"} \ No newline at end of file diff --git a/dist/modules/access/injectRoles.d.js b/dist/modules/access/injectRoles.d.js deleted file mode 100644 index 98150da..0000000 --- a/dist/modules/access/injectRoles.d.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Injects the fixed `roles` field into the client's auth collection. - * - * The plugin owns the role definition; the client owns the collection. This - * finds the collection by slug and appends the field. We control the whole - * stack, so no conflict handling is needed — the field is simply added. - */ export { }; - -//# sourceMappingURL=injectRoles.d.js.map \ No newline at end of file diff --git a/dist/modules/access/injectRoles.d.js.map b/dist/modules/access/injectRoles.d.js.map deleted file mode 100644 index b39baa0..0000000 --- a/dist/modules/access/injectRoles.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["injectRoles.d.ts"],"sourcesContent":["import type { Config } from 'payload';\nimport type { AccessOption } from './types.js';\n/**\n * Injects the fixed `roles` field into the client's auth collection.\n *\n * The plugin owns the role definition; the client owns the collection. This\n * finds the collection by slug and appends the field. We control the whole\n * stack, so no conflict handling is needed — the field is simply added.\n */\nexport declare function injectRoles(config: Config, access: AccessOption): Config;\n"],"names":[],"mappings":"AAEA;;;;;;CAMC,GACD,WAAkF"} \ No newline at end of file diff --git a/dist/modules/access/predicates.d.js b/dist/modules/access/predicates.d.js deleted file mode 100644 index 1349e70..0000000 --- a/dist/modules/access/predicates.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=predicates.d.js.map \ No newline at end of file diff --git a/dist/modules/access/predicates.d.js.map b/dist/modules/access/predicates.d.js.map deleted file mode 100644 index f1d72b6..0000000 --- a/dist/modules/access/predicates.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["predicates.d.ts"],"sourcesContent":["import type { Role } from './types.js';\n/**\n * The plugin can't know the client's generated User type, and Payload types\n * `req.user` loosely (UntypedUser | null). Predicates therefore accept an\n * unknown-ish user and read `roles` defensively — no assumptions about shape\n * beyond an optional roles array.\n */\ntype MaybeUser = {\n roles?: null | Role[];\n} | null | Record | undefined;\n/**\n * True if the user holds at least the given role in the hierarchy.\n * admin satisfies 'editor' and 'user'; editor satisfies 'user'.\n */\nexport declare function hasMinimumRole(user: MaybeUser, minimum: Role): boolean;\n/** True if the user is an admin. */\nexport declare function isAdmin(user: MaybeUser): boolean;\n/** True if the user is an editor or higher (editor, admin). */\nexport declare function isEditor(user: MaybeUser): boolean;\nexport {};\n"],"names":[],"mappings":"AAmBA,WAAU"} \ No newline at end of file diff --git a/dist/modules/access/rolesField.d.js b/dist/modules/access/rolesField.d.js deleted file mode 100644 index 9a55fa1..0000000 --- a/dist/modules/access/rolesField.d.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Builds the fixed `roles` field the plugin injects into the auth collection. - * - * Saved to the JWT so role checks avoid a database lookup. Only admins can - * change roles, preventing privilege escalation by lower-privilege users. - */ export { }; - -//# sourceMappingURL=rolesField.d.js.map \ No newline at end of file diff --git a/dist/modules/access/rolesField.d.js.map b/dist/modules/access/rolesField.d.js.map deleted file mode 100644 index 8016ab2..0000000 --- a/dist/modules/access/rolesField.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["rolesField.d.ts"],"sourcesContent":["import type { Field } from 'payload';\nimport type { Role } from './types.js';\n/**\n * Builds the fixed `roles` field the plugin injects into the auth collection.\n *\n * Saved to the JWT so role checks avoid a database lookup. Only admins can\n * change roles, preventing privilege escalation by lower-privilege users.\n */\nexport declare function buildRolesField(defaultRole?: Role): Field;\n"],"names":[],"mappings":"AAEA;;;;;CAKC,GACD,WAAmE"} \ No newline at end of file diff --git a/dist/modules/access/types.d.js b/dist/modules/access/types.d.js deleted file mode 100644 index e9eeb54..0000000 --- a/dist/modules/access/types.d.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Role hierarchy, lowest to highest privilege. - * A higher role satisfies any requirement met by a lower one. - */ /** - * Access-control options. - * - * The plugin injects a fixed `roles` field into the client's auth collection - * — the collection itself belongs to the client (create-payload-app), the - * role definition belongs to the plugin. - */ export { }; - -//# sourceMappingURL=types.d.js.map \ No newline at end of file diff --git a/dist/modules/access/types.d.js.map b/dist/modules/access/types.d.js.map deleted file mode 100644 index 7d2c1ee..0000000 --- a/dist/modules/access/types.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["types.d.ts"],"sourcesContent":["/**\n * Role hierarchy, lowest to highest privilege.\n * A higher role satisfies any requirement met by a lower one.\n */\nexport declare const ROLE_HIERARCHY: readonly [\"user\", \"editor\", \"admin\"];\nexport type Role = (typeof ROLE_HIERARCHY)[number];\n/**\n * Access-control options.\n *\n * The plugin injects a fixed `roles` field into the client's auth collection\n * — the collection itself belongs to the client (create-payload-app), the\n * role definition belongs to the plugin.\n */\nexport type AccessOption = {\n /** Slug of the client's auth collection, e.g. 'users'. */\n authCollection: string;\n /** Role assigned to new users. Defaults to 'user'. */\n defaultRole?: Role;\n};\n"],"names":[],"mappings":"AAAA;;;CAGC,GAGD;;;;;;CAMC,GACD,WAKE"} \ No newline at end of file diff --git a/dist/modules/analytics/Analytics.d.js b/dist/modules/analytics/Analytics.d.js deleted file mode 100644 index 2244182..0000000 --- a/dist/modules/analytics/Analytics.d.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Loads Google Analytics — GTM if a container ID is set, otherwise GA4 gtag. - * - * Consent Mode is initialised to the visitor's stored consent BEFORE the tag - * loads (via setDefaultConsent from the consent module), so tags respect the - * choice from the first hit; useConsent sends an update the moment the visitor - * decides. IDs are public and come from SiteIntegrations, passed in as props - * (the client project reads them server-side). - * - * Renders nothing — it only injects the scripts. Mount once, high in the tree - * (e.g. root layout), inside ConsentProvider. - */ export { }; - -//# sourceMappingURL=Analytics.d.js.map \ No newline at end of file diff --git a/dist/modules/analytics/Analytics.d.js.map b/dist/modules/analytics/Analytics.d.js.map deleted file mode 100644 index 705a67f..0000000 --- a/dist/modules/analytics/Analytics.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["Analytics.d.ts"],"sourcesContent":["import type { AnalyticsConfig } from './types.js';\ndeclare global {\n interface Window {\n dataLayer?: unknown[];\n }\n}\n/**\n * Loads Google Analytics — GTM if a container ID is set, otherwise GA4 gtag.\n *\n * Consent Mode is initialised to the visitor's stored consent BEFORE the tag\n * loads (via setDefaultConsent from the consent module), so tags respect the\n * choice from the first hit; useConsent sends an update the moment the visitor\n * decides. IDs are public and come from SiteIntegrations, passed in as props\n * (the client project reads them server-side).\n *\n * Renders nothing — it only injects the scripts. Mount once, high in the tree\n * (e.g. root layout), inside ConsentProvider.\n */\nexport declare function Analytics({ ga4MeasurementId, gtmContainerId }: AnalyticsConfig): null;\n"],"names":[],"mappings":"AAMA;;;;;;;;;;;CAWC,GACD,WAA+F"} \ No newline at end of file diff --git a/dist/modules/analytics/client.d.js b/dist/modules/analytics/client.d.js deleted file mode 100644 index d3ef406..0000000 --- a/dist/modules/analytics/client.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { Analytics } from './Analytics.js'; - -//# sourceMappingURL=client.d.js.map \ No newline at end of file diff --git a/dist/modules/analytics/client.d.js.map b/dist/modules/analytics/client.d.js.map deleted file mode 100644 index 8a5b4d6..0000000 --- a/dist/modules/analytics/client.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["client.d.ts"],"sourcesContent":["export { Analytics } from './Analytics.js';\n"],"names":["Analytics"],"mappings":"AAAA,SAASA,SAAS,QAAQ,iBAAiB"} \ No newline at end of file diff --git a/dist/modules/analytics/getAnalyticsConfig.d.js b/dist/modules/analytics/getAnalyticsConfig.d.js deleted file mode 100644 index 9fbed95..0000000 --- a/dist/modules/analytics/getAnalyticsConfig.d.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Reads the public analytics IDs from SiteIntegrations, server-side. - * - * Returns only the two public IDs (GA4 / GTM) — safe to pass to the client - * component. Does NOT expose any secret from SiteIntegrations. - */ export { }; - -//# sourceMappingURL=getAnalyticsConfig.d.js.map \ No newline at end of file diff --git a/dist/modules/analytics/getAnalyticsConfig.d.js.map b/dist/modules/analytics/getAnalyticsConfig.d.js.map deleted file mode 100644 index 96be816..0000000 --- a/dist/modules/analytics/getAnalyticsConfig.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["getAnalyticsConfig.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { AnalyticsConfig } from './types.js';\n/**\n * Reads the public analytics IDs from SiteIntegrations, server-side.\n *\n * Returns only the two public IDs (GA4 / GTM) — safe to pass to the client\n * component. Does NOT expose any secret from SiteIntegrations.\n */\nexport declare function getAnalyticsConfig(payload: BasePayload): Promise;\n"],"names":[],"mappings":"AAEA;;;;;CAKC,GACD,WAA2F"} \ No newline at end of file diff --git a/dist/modules/analytics/index.d.js b/dist/modules/analytics/index.d.js deleted file mode 100644 index 016dab0..0000000 --- a/dist/modules/analytics/index.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { getAnalyticsConfig } from './getAnalyticsConfig.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/analytics/index.d.js.map b/dist/modules/analytics/index.d.js.map deleted file mode 100644 index fe5de2d..0000000 --- a/dist/modules/analytics/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export type { AnalyticsConfig } from './types.js';\nexport { getAnalyticsConfig } from './getAnalyticsConfig.js';\n"],"names":["getAnalyticsConfig"],"mappings":"AACA,SAASA,kBAAkB,QAAQ,0BAA0B"} \ No newline at end of file diff --git a/dist/modules/analytics/index.d.ts b/dist/modules/analytics/index.d.ts index 776468d..b37bdc1 100644 --- a/dist/modules/analytics/index.d.ts +++ b/dist/modules/analytics/index.d.ts @@ -1,2 +1,2 @@ -export type { AnalyticsConfig } from './types.js'; export { getAnalyticsConfig } from './getAnalyticsConfig.js'; +export type { AnalyticsConfig } from './types.js'; diff --git a/dist/modules/analytics/index.js b/dist/modules/analytics/index.js index 11b6e49..f943ce4 100644 --- a/dist/modules/analytics/index.js +++ b/dist/modules/analytics/index.js @@ -1,5 +1,3 @@ -// Server-safe: config type + the helper that reads IDs from SiteIntegrations. -// The component is client-side — exported via ./client. export { getAnalyticsConfig } from './getAnalyticsConfig.js'; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/modules/analytics/index.js.map b/dist/modules/analytics/index.js.map index 8a3ea22..e42ecb9 100644 --- a/dist/modules/analytics/index.js.map +++ b/dist/modules/analytics/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../../src/modules/analytics/index.ts"],"sourcesContent":["// Server-safe: config type + the helper that reads IDs from SiteIntegrations.\n// The component is client-side — exported via ./client.\nexport type { AnalyticsConfig } from './types.js'\nexport { getAnalyticsConfig } from './getAnalyticsConfig.js'\n"],"names":["getAnalyticsConfig"],"mappings":"AAAA,8EAA8E;AAC9E,oEAAoE;AAEpE,SAASA,kBAAkB,QAAQ,0BAAyB"} \ No newline at end of file +{"version":3,"sources":["../../../src/modules/analytics/index.ts"],"sourcesContent":["export { getAnalyticsConfig } from './getAnalyticsConfig.js'\n// Server-safe: config type + the helper that reads IDs from SiteIntegrations.\n// The component is client-side — exported via ./client.\nexport type { AnalyticsConfig } from './types.js'\n"],"names":["getAnalyticsConfig"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,0BAAyB"} \ No newline at end of file diff --git a/dist/modules/analytics/types.d.js b/dist/modules/analytics/types.d.js deleted file mode 100644 index ba7eb3f..0000000 --- a/dist/modules/analytics/types.d.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Analytics IDs, read from SiteIntegrations (public — safe on the client). - */ export { }; - -//# sourceMappingURL=types.d.js.map \ No newline at end of file diff --git a/dist/modules/analytics/types.d.js.map b/dist/modules/analytics/types.d.js.map deleted file mode 100644 index 76339cb..0000000 --- a/dist/modules/analytics/types.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["types.d.ts"],"sourcesContent":["/**\n * Analytics IDs, read from SiteIntegrations (public — safe on the client).\n */\nexport type AnalyticsConfig = {\n /** GA4 Measurement ID, e.g. 'G-XXXXXXXXXX'. */\n ga4MeasurementId?: null | string;\n /** GTM Container ID, e.g. 'GTM-XXXXXXX'. */\n gtmContainerId?: null | string;\n};\n"],"names":[],"mappings":"AAAA;;CAEC,GACD,WAKE"} \ No newline at end of file diff --git a/dist/modules/blocks/RenderBlocks.d.js b/dist/modules/blocks/RenderBlocks.d.js deleted file mode 100644 index 3f1e411..0000000 --- a/dist/modules/blocks/RenderBlocks.d.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Generic, server-side block renderer. - * - * Iterates a document's blocks and renders each via the client's component - * map. Unknown blocks are skipped (null), never thrown. Block-specific logic is - * delegated to the client's optional `enhanceProps` — the plugin itself is - * block-agnostic. - * - * The client owns components and block schemas (they pass `components` and - * define blocks in their config); the plugin owns only the iteration and - * wiring. No wrapper markup is added — spacing/layout belong to the client's - * components. - * - * Nested blocks: a block that needs to render child blocks should render its - * own and import the registry itself, rather than receiving the - * component map as a prop. Passing the map as a prop breaks React Server - * Components — functions (client components) can't cross the server→client - * boundary via props. - */ export { }; - -//# sourceMappingURL=RenderBlocks.d.js.map \ No newline at end of file diff --git a/dist/modules/blocks/RenderBlocks.d.js.map b/dist/modules/blocks/RenderBlocks.d.js.map deleted file mode 100644 index 5d542e8..0000000 --- a/dist/modules/blocks/RenderBlocks.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["RenderBlocks.d.ts"],"sourcesContent":["import type { BlockComponentMap, BlockData, EnhanceProps } from './types.js';\nexport type RenderBlocksProps = {\n /** Block data array from a Payload document (e.g. page.layout). */\n blocks: BlockData[] | null | undefined;\n /** Client-provided map of blockType → component. */\n components: BlockComponentMap;\n /**\n * Optional client hook to inject block-specific props (nav anchors, etc.).\n * Keeps the engine generic — the plugin knows no concrete block types.\n */\n enhanceProps?: EnhanceProps;\n};\n/**\n * Generic, server-side block renderer.\n *\n * Iterates a document's blocks and renders each via the client's component\n * map. Unknown blocks are skipped (null), never thrown. Block-specific logic is\n * delegated to the client's optional `enhanceProps` — the plugin itself is\n * block-agnostic.\n *\n * The client owns components and block schemas (they pass `components` and\n * define blocks in their config); the plugin owns only the iteration and\n * wiring. No wrapper markup is added — spacing/layout belong to the client's\n * components.\n *\n * Nested blocks: a block that needs to render child blocks should render its\n * own and import the registry itself, rather than receiving the\n * component map as a prop. Passing the map as a prop breaks React Server\n * Components — functions (client components) can't cross the server→client\n * boundary via props.\n */\nexport declare function RenderBlocks({ blocks, components, enhanceProps }: RenderBlocksProps): import(\"react/jsx-runtime\").JSX.Element | null;\n"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;CAkBC,GACD,WAA8I"} \ No newline at end of file diff --git a/dist/modules/blocks/index.d.js b/dist/modules/blocks/index.d.js deleted file mode 100644 index f9d06ce..0000000 --- a/dist/modules/blocks/index.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { RenderBlocks } from './RenderBlocks.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/blocks/index.d.js.map b/dist/modules/blocks/index.d.js.map deleted file mode 100644 index 5a0d7d0..0000000 --- a/dist/modules/blocks/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { RenderBlocks } from './RenderBlocks.js';\nexport type { RenderBlocksProps } from './RenderBlocks.js';\nexport type { BlockComponentMap, BlockData, EnhanceProps } from './types.js';\n"],"names":["RenderBlocks"],"mappings":"AAAA,SAASA,YAAY,QAAQ,oBAAoB"} \ No newline at end of file diff --git a/dist/modules/blocks/types.d.js b/dist/modules/blocks/types.d.js deleted file mode 100644 index d98e6b8..0000000 --- a/dist/modules/blocks/types.d.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Optional per-block prop enhancer supplied by the client. - * - * Lets the client inject block-specific logic (e.g. collect anchors for a nav - * block) without the plugin knowing any concrete block types. Returns extra - * props merged into the rendered block. - */ export { }; - -//# sourceMappingURL=types.d.js.map \ No newline at end of file diff --git a/dist/modules/blocks/types.d.js.map b/dist/modules/blocks/types.d.js.map deleted file mode 100644 index a84c798..0000000 --- a/dist/modules/blocks/types.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["types.d.ts"],"sourcesContent":["import type { ComponentType } from 'react';\n/**\n * A single block's data as stored by Payload — always has a blockType, plus\n * arbitrary block-specific fields. The plugin stays generic over the shape.\n */\nexport type BlockData = {\n [key: string]: unknown;\n blockType: string;\n};\n/**\n * Maps a blockType to the client's component for it.\n * The client owns the components; the plugin only receives this map.\n */\nexport type BlockComponentMap = Record>;\n/**\n * Optional per-block prop enhancer supplied by the client.\n *\n * Lets the client inject block-specific logic (e.g. collect anchors for a nav\n * block) without the plugin knowing any concrete block types. Returns extra\n * props merged into the rendered block.\n */\nexport type EnhanceProps = (args: {\n allBlocks: BlockData[];\n block: BlockData;\n index: number;\n}) => Record;\n"],"names":[],"mappings":"AAcA;;;;;;CAMC,GACD,WAI8B"} \ No newline at end of file diff --git a/dist/modules/consent/ConsentContext.d.js b/dist/modules/consent/ConsentContext.d.js deleted file mode 100644 index 2d8f9c0..0000000 --- a/dist/modules/consent/ConsentContext.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=ConsentContext.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/ConsentContext.d.js.map b/dist/modules/consent/ConsentContext.d.js.map deleted file mode 100644 index 272b3d3..0000000 --- a/dist/modules/consent/ConsentContext.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["ConsentContext.d.ts"],"sourcesContent":["import { type ReactNode } from 'react';\nimport type { ConsentTexts } from './texts.js';\nimport { useConsent } from './useConsent.js';\ntype ConsentContextValue = {\n texts: ConsentTexts;\n} & ReturnType;\nexport declare function ConsentProvider({ children, texts }: {\n children: ReactNode;\n texts: ConsentTexts;\n}): import(\"react/jsx-runtime\").JSX.Element;\nexport declare function useConsentContext(): ConsentContextValue;\nexport {};\n"],"names":[],"mappings":"AAWA,WAAU"} \ No newline at end of file diff --git a/dist/modules/consent/CookieBanner.d.js b/dist/modules/consent/CookieBanner.d.js deleted file mode 100644 index 46e14b0..0000000 --- a/dist/modules/consent/CookieBanner.d.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Optional class overrides — for when tokens aren't enough, e.g. turning the - * bottom bar into a centred modal. Replaces the slot's classes outright. - */ export { }; - -//# sourceMappingURL=CookieBanner.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/CookieBanner.d.js.map b/dist/modules/consent/CookieBanner.d.js.map deleted file mode 100644 index 3bc1a8a..0000000 --- a/dist/modules/consent/CookieBanner.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["CookieBanner.d.ts"],"sourcesContent":["/**\n * Optional class overrides — for when tokens aren't enough, e.g. turning the\n * bottom bar into a centred modal. Replaces the slot's classes outright.\n */\nexport type CookieBannerClassNames = {\n primaryButton?: string;\n root?: string;\n secondaryButton?: string;\n};\nexport declare function CookieBanner({ classNames }?: {\n classNames?: CookieBannerClassNames;\n}): import(\"react/jsx-runtime\").JSX.Element | null;\n"],"names":[],"mappings":"AAAA;;;CAGC,GAMD,WAEmD"} \ No newline at end of file diff --git a/dist/modules/consent/CookieButton.d.js b/dist/modules/consent/CookieButton.d.js deleted file mode 100644 index b627aec..0000000 --- a/dist/modules/consent/CookieButton.d.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Floating "cookie settings" button — lets visitors reopen the consent panel - * after deciding (GDPR: withdrawing consent must be as easy as giving it). - * Hidden while the banner is showing. - * - * Colours follow the same CSS custom properties as CookieBanner - * (--ipal-surface, --ipal-border, --ipal-hover, --ipal-text), so a client's - * palette applies to both without touching either component. Pass className to - * replace the styling outright. - */ export { }; - -//# sourceMappingURL=CookieButton.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/CookieButton.d.js.map b/dist/modules/consent/CookieButton.d.js.map deleted file mode 100644 index f493d3b..0000000 --- a/dist/modules/consent/CookieButton.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["CookieButton.d.ts"],"sourcesContent":["/**\n * Floating \"cookie settings\" button — lets visitors reopen the consent panel\n * after deciding (GDPR: withdrawing consent must be as easy as giving it).\n * Hidden while the banner is showing.\n *\n * Colours follow the same CSS custom properties as CookieBanner\n * (--ipal-surface, --ipal-border, --ipal-hover, --ipal-text), so a client's\n * palette applies to both without touching either component. Pass className to\n * replace the styling outright.\n */\nexport declare function CookieButton({ className }?: {\n className?: string;\n}): import(\"react/jsx-runtime\").JSX.Element | null;\n"],"names":[],"mappings":"AAAA;;;;;;;;;CASC,GACD,WAEmD"} \ No newline at end of file diff --git a/dist/modules/consent/categories.d.js b/dist/modules/consent/categories.d.js deleted file mode 100644 index c59e3ef..0000000 --- a/dist/modules/consent/categories.d.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Cookie consent categories (GDPR). 'necessary' is always granted and cannot be - * disabled. The rest default to false until the user opts in. - */ export { }; - -//# sourceMappingURL=categories.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/categories.d.js.map b/dist/modules/consent/categories.d.js.map deleted file mode 100644 index b7bac6f..0000000 --- a/dist/modules/consent/categories.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["categories.d.ts"],"sourcesContent":["/**\n * Cookie consent categories (GDPR). 'necessary' is always granted and cannot be\n * disabled. The rest default to false until the user opts in.\n */\nexport declare const CONSENT_CATEGORIES: readonly [\"necessary\", \"functional\", \"analytics\", \"marketing\"];\nexport type ConsentCategory = (typeof CONSENT_CATEGORIES)[number];\nexport type ConsentState = Record;\nexport declare const DEFAULT_CONSENT: ConsentState;\nexport declare const ACCEPT_ALL_CONSENT: ConsentState;\nexport declare const REJECT_ALL_CONSENT: ConsentState;\n"],"names":[],"mappings":"AAAA;;;CAGC,GAMD,WAAsD"} \ No newline at end of file diff --git a/dist/modules/consent/client.d.js b/dist/modules/consent/client.d.js deleted file mode 100644 index 4384a0d..0000000 --- a/dist/modules/consent/client.d.js +++ /dev/null @@ -1,6 +0,0 @@ -export { ConsentProvider, useConsentContext } from './ConsentContext.js'; -export { CookieBanner } from './CookieBanner.js'; -export { CookieButton } from './CookieButton.js'; -export { useConsent } from './useConsent.js'; - -//# sourceMappingURL=client.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/client.d.js.map b/dist/modules/consent/client.d.js.map deleted file mode 100644 index 95c3d1d..0000000 --- a/dist/modules/consent/client.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["client.d.ts"],"sourcesContent":["export { ConsentProvider, useConsentContext } from './ConsentContext.js';\nexport { CookieBanner } from './CookieBanner.js';\nexport type { CookieBannerClassNames } from './CookieBanner.js';\nexport { CookieButton } from './CookieButton.js';\nexport { useConsent } from './useConsent.js';\n"],"names":["ConsentProvider","useConsentContext","CookieBanner","CookieButton","useConsent"],"mappings":"AAAA,SAASA,eAAe,EAAEC,iBAAiB,QAAQ,sBAAsB;AACzE,SAASC,YAAY,QAAQ,oBAAoB;AAEjD,SAASC,YAAY,QAAQ,oBAAoB;AACjD,SAASC,UAAU,QAAQ,kBAAkB"} \ No newline at end of file diff --git a/dist/modules/consent/getConsentTexts.d.js b/dist/modules/consent/getConsentTexts.d.js deleted file mode 100644 index 0ce0bca..0000000 --- a/dist/modules/consent/getConsentTexts.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=getConsentTexts.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/getConsentTexts.d.js.map b/dist/modules/consent/getConsentTexts.d.js.map deleted file mode 100644 index 2fb6636..0000000 --- a/dist/modules/consent/getConsentTexts.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["getConsentTexts.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { I18nConfig } from '../i18n/index.js';\nimport type { ConsentTexts } from './texts.js';\ntype GetConsentTextsArgs = {\n config: I18nConfig;\n locale?: string;\n payload: BasePayload;\n /**\n * Privacy-policy label + the system page (from SiteSettings.privacyPolicy,\n * read with locale:'all') to link to. Optional — omit for no link.\n */\n privacyPolicy?: {\n label: string;\n page: {\n slug?: null | Record;\n } | null;\n };\n};\n/**\n * Resolves consent banner texts from the CookieSettings global, falling back to\n * English defaults per field. The privacy-policy link is built from the pages\n * module (system page role), not stored in CookieSettings — one source of truth.\n */\nexport declare function getConsentTexts({ config, locale, payload, privacyPolicy, }: GetConsentTextsArgs): Promise;\nexport {};\n"],"names":[],"mappings":"AAwBA,WAAU"} \ No newline at end of file diff --git a/dist/modules/consent/googleConsent.d.js b/dist/modules/consent/googleConsent.d.js deleted file mode 100644 index 946971a..0000000 --- a/dist/modules/consent/googleConsent.d.js +++ /dev/null @@ -1,3 +0,0 @@ -/** Updates consent after the user decides. */ export { }; - -//# sourceMappingURL=googleConsent.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/googleConsent.d.js.map b/dist/modules/consent/googleConsent.d.js.map deleted file mode 100644 index 913715c..0000000 --- a/dist/modules/consent/googleConsent.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["googleConsent.d.ts"],"sourcesContent":["import type { ConsentState } from './categories.js';\ndeclare global {\n interface Window {\n dataLayer?: unknown[];\n }\n}\n/**\n * Mirrors Google's canonical snippet: `function gtag(){dataLayer.push(arguments)}`.\n *\n * Pushing `arguments` rather than a plain array is not a stylistic detail.\n * Google's tags recognise a consent command by the Arguments object it arrives\n * in; a real array lands in the dataLayer as ordinary data and the command is\n * silently ignored — the tag loads, but consent never updates and analytics\n * stays denied. The rest parameter exists only to type the call sites.\n *\n * Exported for the analytics module (which needs `js`/`config` commands) —\n * intentionally not re-exported from the package's public API.\n */\nexport declare function gtag(..._args: unknown[]): void;\n/** Sets the default consent state (call before Google tags load). */\nexport declare function setDefaultConsent(state: ConsentState): void;\n/** Updates consent after the user decides. */\nexport declare function updateConsent(state: ConsentState): void;\n"],"names":[],"mappings":"AAqBA,4CAA4C,GAC5C,WAAiE"} \ No newline at end of file diff --git a/dist/modules/consent/index.d.js b/dist/modules/consent/index.d.js deleted file mode 100644 index 7823bcc..0000000 --- a/dist/modules/consent/index.d.js +++ /dev/null @@ -1,6 +0,0 @@ -export { ACCEPT_ALL_CONSENT, CONSENT_CATEGORIES, DEFAULT_CONSENT, REJECT_ALL_CONSENT } from './categories.js'; -export { getConsentTexts } from './getConsentTexts.js'; -export { setDefaultConsent, updateConsent } from './googleConsent.js'; -export { CONSENT_COOKIE, CONSENT_MAX_AGE, CONSENT_VERSION, parseConsent, serializeConsent } from './storage.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/index.d.js.map b/dist/modules/consent/index.d.js.map deleted file mode 100644 index 7d991f9..0000000 --- a/dist/modules/consent/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { ACCEPT_ALL_CONSENT, CONSENT_CATEGORIES, DEFAULT_CONSENT, REJECT_ALL_CONSENT, } from './categories.js';\nexport type { ConsentCategory, ConsentState } from './categories.js';\nexport { getConsentTexts } from './getConsentTexts.js';\nexport { setDefaultConsent, updateConsent } from './googleConsent.js';\nexport { CONSENT_COOKIE, CONSENT_MAX_AGE, CONSENT_VERSION, parseConsent, serializeConsent, } from './storage.js';\nexport type { ConsentTexts } from './texts.js';\n"],"names":["ACCEPT_ALL_CONSENT","CONSENT_CATEGORIES","DEFAULT_CONSENT","REJECT_ALL_CONSENT","getConsentTexts","setDefaultConsent","updateConsent","CONSENT_COOKIE","CONSENT_MAX_AGE","CONSENT_VERSION","parseConsent","serializeConsent"],"mappings":"AAAA,SAASA,kBAAkB,EAAEC,kBAAkB,EAAEC,eAAe,EAAEC,kBAAkB,QAAS,kBAAkB;AAE/G,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,iBAAiB,EAAEC,aAAa,QAAQ,qBAAqB;AACtE,SAASC,cAAc,EAAEC,eAAe,EAAEC,eAAe,EAAEC,YAAY,EAAEC,gBAAgB,QAAS,eAAe"} \ No newline at end of file diff --git a/dist/modules/consent/storage.d.js b/dist/modules/consent/storage.d.js deleted file mode 100644 index f9d52b7..0000000 --- a/dist/modules/consent/storage.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=storage.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/storage.d.js.map b/dist/modules/consent/storage.d.js.map deleted file mode 100644 index 5033ee9..0000000 --- a/dist/modules/consent/storage.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["storage.d.ts"],"sourcesContent":["import type { ConsentState } from './categories.js';\n/**\n * Consent persistence in a cookie. Stored with a version so we can invalidate\n * old consents when the policy changes, and a timestamp (GDPR: consent must be\n * dated). Readable both client-side (banner) and server-side (script gating).\n */\nexport declare const CONSENT_COOKIE = \"cookie-consent\";\nexport declare const CONSENT_VERSION = 1;\nexport declare const CONSENT_MAX_AGE: number;\nexport declare function serializeConsent(state: ConsentState): string;\nexport declare function parseConsent(raw: string | undefined): ConsentState | null;\n"],"names":[],"mappings":"AAUA,WAAmF"} \ No newline at end of file diff --git a/dist/modules/consent/texts.d.js b/dist/modules/consent/texts.d.js deleted file mode 100644 index 2964578..0000000 --- a/dist/modules/consent/texts.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=texts.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/texts.d.js.map b/dist/modules/consent/texts.d.js.map deleted file mode 100644 index 0838985..0000000 --- a/dist/modules/consent/texts.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["texts.d.ts"],"sourcesContent":["import type { ConsentCategory } from './categories.js';\nexport type ConsentTexts = {\n buttons: {\n acceptAll: string;\n back: string;\n reject: string;\n save: string;\n settings: string;\n };\n categories: Record;\n message: string;\n /** null = no privacy-policy link shown */\n privacyLink: {\n href: string;\n label: string;\n } | null;\n settingsTitle: string;\n};\n"],"names":[],"mappings":"AACA,WAmBE"} \ No newline at end of file diff --git a/dist/modules/consent/useConsent.d.js b/dist/modules/consent/useConsent.d.js deleted file mode 100644 index 1c5a012..0000000 --- a/dist/modules/consent/useConsent.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=useConsent.d.js.map \ No newline at end of file diff --git a/dist/modules/consent/useConsent.d.js.map b/dist/modules/consent/useConsent.d.js.map deleted file mode 100644 index 7a38fb1..0000000 --- a/dist/modules/consent/useConsent.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["useConsent.d.ts"],"sourcesContent":["import type { ConsentCategory, ConsentState } from './categories.js';\nexport declare function useConsent(): {\n acceptAll: () => void;\n decided: boolean;\n rejectAll: () => void;\n reopen: () => void;\n savePreferences: (choices: Partial>) => void;\n state: ConsentState;\n};\n"],"names":[],"mappings":"AACA,WAOE"} \ No newline at end of file diff --git a/dist/modules/consent/useConsent.d.ts b/dist/modules/consent/useConsent.d.ts index 0622592..7468fa0 100644 --- a/dist/modules/consent/useConsent.d.ts +++ b/dist/modules/consent/useConsent.d.ts @@ -1,5 +1,5 @@ import type { ConsentCategory, ConsentState } from './categories.js'; -export declare function useConsent(): { +export declare function useConsent(cookieMap?: Partial>): { acceptAll: () => void; decided: boolean; rejectAll: () => void; diff --git a/dist/modules/consent/useConsent.js b/dist/modules/consent/useConsent.js index f66c2ed..f4ed297 100644 --- a/dist/modules/consent/useConsent.js +++ b/dist/modules/consent/useConsent.js @@ -1,9 +1,22 @@ 'use client'; import { useCallback, useEffect, useState } from 'react'; +import { LOCALE_COOKIE_NAME } from '../i18n/index.js'; import { ACCEPT_ALL_CONSENT, DEFAULT_CONSENT, REJECT_ALL_CONSENT } from './categories.js'; import { updateConsent } from './googleConsent.js'; import { CONSENT_COOKIE, CONSENT_MAX_AGE, parseConsent, serializeConsent } from './storage.js'; -export function useConsent() { +/** + * Cookies to delete when consent for a category is withdrawn. Keyed by + * category. The plugin knows about its own functional cookie (locale); clients + * can extend this via the `cookieMap` arg to useConsent if they set their own. + */ const DEFAULT_COOKIE_MAP = { + functional: [ + LOCALE_COOKIE_NAME + ] +}; +/** Expire a cookie now, across the whole site. */ function deleteCookie(name) { + document.cookie = `${name}=;path=/;max-age=0;samesite=lax`; +} +export function useConsent(cookieMap = DEFAULT_COOKIE_MAP) { const [state, setState] = useState(DEFAULT_CONSENT); const [decided, setDecided] = useState(false); useEffect(()=>{ @@ -15,6 +28,19 @@ export function useConsent() { } }, []); const persist = useCallback((next)=>{ + // Withdrawal cleanup: for any category flipping true → false, delete the + // cookies tied to it. GDPR: withdrawing consent must stop the processing, + // so a functional cookie (e.g. locale) written under consent has to go when + // that consent is revoked. Uses the current `state` as the previous value. + for (const cat of Object.keys(cookieMap)){ + const wasGranted = state[cat] === true; + const nowDenied = next[cat] !== true; + if (wasGranted && nowDenied) { + for (const name of cookieMap[cat] ?? []){ + deleteCookie(name); + } + } + } document.cookie = `${CONSENT_COOKIE}=${serializeConsent(next)};path=/;max-age=${CONSENT_MAX_AGE};samesite=lax`; setState(next); setDecided(true); @@ -23,7 +49,10 @@ export function useConsent() { // the rest of the session and never write their cookies — the banner would // look like it worked while nothing changed. updateConsent(next); - }, []); + }, [ + state, + cookieMap + ]); const acceptAll = useCallback(()=>persist(ACCEPT_ALL_CONSENT), [ persist ]); diff --git a/dist/modules/consent/useConsent.js.map b/dist/modules/consent/useConsent.js.map index 3a761c1..067f9ca 100644 --- a/dist/modules/consent/useConsent.js.map +++ b/dist/modules/consent/useConsent.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../../src/modules/consent/useConsent.ts"],"sourcesContent":["'use client'\nimport { useCallback, useEffect, useState } from 'react'\n\nimport type { ConsentCategory, ConsentState } from './categories.js'\n\nimport { ACCEPT_ALL_CONSENT, DEFAULT_CONSENT, REJECT_ALL_CONSENT } from './categories.js'\nimport { updateConsent } from './googleConsent.js'\nimport { CONSENT_COOKIE, CONSENT_MAX_AGE, parseConsent, serializeConsent } from './storage.js'\n\nexport function useConsent() {\n const [state, setState] = useState(DEFAULT_CONSENT)\n const [decided, setDecided] = useState(false)\n\n useEffect(() => {\n const raw = document.cookie\n .split('; ')\n .find((c) => c.startsWith(`${CONSENT_COOKIE}=`))\n ?.split('=')[1]\n const parsed = parseConsent(raw)\n if (parsed) {\n setState(parsed)\n setDecided(true)\n }\n }, [])\n\n const persist = useCallback((next: ConsentState) => {\n document.cookie = `${CONSENT_COOKIE}=${serializeConsent(next)};path=/;max-age=${CONSENT_MAX_AGE};samesite=lax`\n setState(next)\n setDecided(true)\n // Tell Google right away. Tags are already on the page holding whatever\n // defaults Analytics set at load; without this update they keep them for\n // the rest of the session and never write their cookies — the banner would\n // look like it worked while nothing changed.\n updateConsent(next)\n }, [])\n\n const acceptAll = useCallback(() => persist(ACCEPT_ALL_CONSENT), [persist])\n const rejectAll = useCallback(() => persist(REJECT_ALL_CONSENT), [persist])\n const savePreferences = useCallback(\n (choices: Partial>) =>\n persist({ ...DEFAULT_CONSENT, ...choices, necessary: true }),\n [persist],\n )\n const reopen = useCallback(() => setDecided(false), [])\n\n return { acceptAll, decided, rejectAll, reopen, savePreferences, state }\n}\n"],"names":["useCallback","useEffect","useState","ACCEPT_ALL_CONSENT","DEFAULT_CONSENT","REJECT_ALL_CONSENT","updateConsent","CONSENT_COOKIE","CONSENT_MAX_AGE","parseConsent","serializeConsent","useConsent","state","setState","decided","setDecided","raw","document","cookie","split","find","c","startsWith","parsed","persist","next","acceptAll","rejectAll","savePreferences","choices","necessary","reopen"],"mappings":"AAAA;AACA,SAASA,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAIxD,SAASC,kBAAkB,EAAEC,eAAe,EAAEC,kBAAkB,QAAQ,kBAAiB;AACzF,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,cAAc,EAAEC,eAAe,EAAEC,YAAY,EAAEC,gBAAgB,QAAQ,eAAc;AAE9F,OAAO,SAASC;IACd,MAAM,CAACC,OAAOC,SAAS,GAAGX,SAAuBE;IACjD,MAAM,CAACU,SAASC,WAAW,GAAGb,SAAS;IAEvCD,UAAU;QACR,MAAMe,MAAMC,SAASC,MAAM,CACxBC,KAAK,CAAC,MACNC,IAAI,CAAC,CAACC,IAAMA,EAAEC,UAAU,CAAC,GAAGf,eAAe,CAAC,CAAC,IAC5CY,MAAM,IAAI,CAAC,EAAE;QACjB,MAAMI,SAASd,aAAaO;QAC5B,IAAIO,QAAQ;YACVV,SAASU;YACTR,WAAW;QACb;IACF,GAAG,EAAE;IAEL,MAAMS,UAAUxB,YAAY,CAACyB;QAC3BR,SAASC,MAAM,GAAG,GAAGX,eAAe,CAAC,EAAEG,iBAAiBe,MAAM,gBAAgB,EAAEjB,gBAAgB,aAAa,CAAC;QAC9GK,SAASY;QACTV,WAAW;QACX,wEAAwE;QACxE,yEAAyE;QACzE,2EAA2E;QAC3E,6CAA6C;QAC7CT,cAAcmB;IAChB,GAAG,EAAE;IAEL,MAAMC,YAAY1B,YAAY,IAAMwB,QAAQrB,qBAAqB;QAACqB;KAAQ;IAC1E,MAAMG,YAAY3B,YAAY,IAAMwB,QAAQnB,qBAAqB;QAACmB;KAAQ;IAC1E,MAAMI,kBAAkB5B,YACtB,CAAC6B,UACCL,QAAQ;YAAE,GAAGpB,eAAe;YAAE,GAAGyB,OAAO;YAAEC,WAAW;QAAK,IAC5D;QAACN;KAAQ;IAEX,MAAMO,SAAS/B,YAAY,IAAMe,WAAW,QAAQ,EAAE;IAEtD,OAAO;QAAEW;QAAWZ;QAASa;QAAWI;QAAQH;QAAiBhB;IAAM;AACzE"} \ No newline at end of file +{"version":3,"sources":["../../../src/modules/consent/useConsent.ts"],"sourcesContent":["'use client'\nimport { useCallback, useEffect, useState } from 'react'\n\nimport type { ConsentCategory, ConsentState } from './categories.js'\n\nimport { LOCALE_COOKIE_NAME } from '../i18n/index.js'\nimport { ACCEPT_ALL_CONSENT, DEFAULT_CONSENT, REJECT_ALL_CONSENT } from './categories.js'\nimport { updateConsent } from './googleConsent.js'\nimport { CONSENT_COOKIE, CONSENT_MAX_AGE, parseConsent, serializeConsent } from './storage.js'\n\n/**\n * Cookies to delete when consent for a category is withdrawn. Keyed by\n * category. The plugin knows about its own functional cookie (locale); clients\n * can extend this via the `cookieMap` arg to useConsent if they set their own.\n */\nconst DEFAULT_COOKIE_MAP: Partial> = {\n functional: [LOCALE_COOKIE_NAME],\n}\n\n/** Expire a cookie now, across the whole site. */\nfunction deleteCookie(name: string) {\n document.cookie = `${name}=;path=/;max-age=0;samesite=lax`\n}\n\nexport function useConsent(\n cookieMap: Partial> = DEFAULT_COOKIE_MAP,\n) {\n const [state, setState] = useState(DEFAULT_CONSENT)\n const [decided, setDecided] = useState(false)\n\n useEffect(() => {\n const raw = document.cookie\n .split('; ')\n .find((c) => c.startsWith(`${CONSENT_COOKIE}=`))\n ?.split('=')[1]\n const parsed = parseConsent(raw)\n if (parsed) {\n setState(parsed)\n setDecided(true)\n }\n }, [])\n\n const persist = useCallback(\n (next: ConsentState) => {\n // Withdrawal cleanup: for any category flipping true → false, delete the\n // cookies tied to it. GDPR: withdrawing consent must stop the processing,\n // so a functional cookie (e.g. locale) written under consent has to go when\n // that consent is revoked. Uses the current `state` as the previous value.\n for (const cat of Object.keys(cookieMap) as ConsentCategory[]) {\n const wasGranted = state[cat] === true\n const nowDenied = next[cat] !== true\n if (wasGranted && nowDenied) {\n for (const name of cookieMap[cat] ?? []) {deleteCookie(name)}\n }\n }\n\n document.cookie = `${CONSENT_COOKIE}=${serializeConsent(next)};path=/;max-age=${CONSENT_MAX_AGE};samesite=lax`\n setState(next)\n setDecided(true)\n // Tell Google right away. Tags are already on the page holding whatever\n // defaults Analytics set at load; without this update they keep them for\n // the rest of the session and never write their cookies — the banner would\n // look like it worked while nothing changed.\n updateConsent(next)\n },\n [state, cookieMap],\n )\n\n const acceptAll = useCallback(() => persist(ACCEPT_ALL_CONSENT), [persist])\n const rejectAll = useCallback(() => persist(REJECT_ALL_CONSENT), [persist])\n const savePreferences = useCallback(\n (choices: Partial>) =>\n persist({ ...DEFAULT_CONSENT, ...choices, necessary: true }),\n [persist],\n )\n const reopen = useCallback(() => setDecided(false), [])\n\n return { acceptAll, decided, rejectAll, reopen, savePreferences, state }\n}\n"],"names":["useCallback","useEffect","useState","LOCALE_COOKIE_NAME","ACCEPT_ALL_CONSENT","DEFAULT_CONSENT","REJECT_ALL_CONSENT","updateConsent","CONSENT_COOKIE","CONSENT_MAX_AGE","parseConsent","serializeConsent","DEFAULT_COOKIE_MAP","functional","deleteCookie","name","document","cookie","useConsent","cookieMap","state","setState","decided","setDecided","raw","split","find","c","startsWith","parsed","persist","next","cat","Object","keys","wasGranted","nowDenied","acceptAll","rejectAll","savePreferences","choices","necessary","reopen"],"mappings":"AAAA;AACA,SAASA,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAIxD,SAASC,kBAAkB,QAAQ,mBAAkB;AACrD,SAASC,kBAAkB,EAAEC,eAAe,EAAEC,kBAAkB,QAAQ,kBAAiB;AACzF,SAASC,aAAa,QAAQ,qBAAoB;AAClD,SAASC,cAAc,EAAEC,eAAe,EAAEC,YAAY,EAAEC,gBAAgB,QAAQ,eAAc;AAE9F;;;;CAIC,GACD,MAAMC,qBAAiE;IACrEC,YAAY;QAACV;KAAmB;AAClC;AAEA,gDAAgD,GAChD,SAASW,aAAaC,IAAY;IAChCC,SAASC,MAAM,GAAG,GAAGF,KAAK,+BAA+B,CAAC;AAC5D;AAEA,OAAO,SAASG,WACdC,YAAwDP,kBAAkB;IAE1E,MAAM,CAACQ,OAAOC,SAAS,GAAGnB,SAAuBG;IACjD,MAAM,CAACiB,SAASC,WAAW,GAAGrB,SAAS;IAEvCD,UAAU;QACR,MAAMuB,MAAMR,SAASC,MAAM,CACxBQ,KAAK,CAAC,MACNC,IAAI,CAAC,CAACC,IAAMA,EAAEC,UAAU,CAAC,GAAGpB,eAAe,CAAC,CAAC,IAC5CiB,MAAM,IAAI,CAAC,EAAE;QACjB,MAAMI,SAASnB,aAAac;QAC5B,IAAIK,QAAQ;YACVR,SAASQ;YACTN,WAAW;QACb;IACF,GAAG,EAAE;IAEL,MAAMO,UAAU9B,YACd,CAAC+B;QACC,yEAAyE;QACzE,0EAA0E;QAC1E,4EAA4E;QAC5E,2EAA2E;QAC3E,KAAK,MAAMC,OAAOC,OAAOC,IAAI,CAACf,WAAiC;YAC7D,MAAMgB,aAAaf,KAAK,CAACY,IAAI,KAAK;YAClC,MAAMI,YAAYL,IAAI,CAACC,IAAI,KAAK;YAChC,IAAIG,cAAcC,WAAW;gBAC3B,KAAK,MAAMrB,QAAQI,SAAS,CAACa,IAAI,IAAI,EAAE,CAAE;oBAAClB,aAAaC;gBAAK;YAC9D;QACF;QAEAC,SAASC,MAAM,GAAG,GAAGT,eAAe,CAAC,EAAEG,iBAAiBoB,MAAM,gBAAgB,EAAEtB,gBAAgB,aAAa,CAAC;QAC9GY,SAASU;QACTR,WAAW;QACX,wEAAwE;QACxE,yEAAyE;QACzE,2EAA2E;QAC3E,6CAA6C;QAC7ChB,cAAcwB;IAChB,GACA;QAACX;QAAOD;KAAU;IAGpB,MAAMkB,YAAYrC,YAAY,IAAM8B,QAAQ1B,qBAAqB;QAAC0B;KAAQ;IAC1E,MAAMQ,YAAYtC,YAAY,IAAM8B,QAAQxB,qBAAqB;QAACwB;KAAQ;IAC1E,MAAMS,kBAAkBvC,YACtB,CAACwC,UACCV,QAAQ;YAAE,GAAGzB,eAAe;YAAE,GAAGmC,OAAO;YAAEC,WAAW;QAAK,IAC5D;QAACX;KAAQ;IAEX,MAAMY,SAAS1C,YAAY,IAAMuB,WAAW,QAAQ,EAAE;IAEtD,OAAO;QAAEc;QAAWf;QAASgB;QAAWI;QAAQH;QAAiBnB;IAAM;AACzE"} \ No newline at end of file diff --git a/dist/modules/content/archiveFields.d.js b/dist/modules/content/archiveFields.d.js deleted file mode 100644 index 475374e..0000000 --- a/dist/modules/content/archiveFields.d.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Builds one relationship field per content collection, pointing at the - * client's Pages collection. - * - * Sits alongside the system-page roles (homepage, privacy policy) because it's - * the same idea: a page referenced by function rather than by slug. The - * assignment is locale-agnostic — one page document — while the resulting path - * is locale-aware, since the page's slug is localized. Assign the "Artykuły" - * page once and you get /pl/artykuly and /en/articles from its own slugs. - */ export { }; - -//# sourceMappingURL=archiveFields.d.js.map \ No newline at end of file diff --git a/dist/modules/content/archiveFields.d.js.map b/dist/modules/content/archiveFields.d.js.map deleted file mode 100644 index fcc6873..0000000 --- a/dist/modules/content/archiveFields.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["archiveFields.d.ts"],"sourcesContent":["import type { Field } from 'payload';\nimport type { ContentOption } from './types.js';\n/**\n * Builds one relationship field per content collection, pointing at the\n * client's Pages collection.\n *\n * Sits alongside the system-page roles (homepage, privacy policy) because it's\n * the same idea: a page referenced by function rather than by slug. The\n * assignment is locale-agnostic — one page document — while the resulting path\n * is locale-aware, since the page's slug is localized. Assign the \"Artykuły\"\n * page once and you get /pl/artykuly and /en/articles from its own slugs.\n */\nexport declare function buildArchiveFields(content: ContentOption, pagesSlug: string): Field[];\n"],"names":[],"mappings":"AAEA;;;;;;;;;CASC,GACD,WAA+F"} \ No newline at end of file diff --git a/dist/modules/content/getArchiveEntries.d.js b/dist/modules/content/getArchiveEntries.d.js deleted file mode 100644 index 836fecf..0000000 --- a/dist/modules/content/getArchiveEntries.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=getArchiveEntries.d.js.map \ No newline at end of file diff --git a/dist/modules/content/getArchiveEntries.d.js.map b/dist/modules/content/getArchiveEntries.d.js.map deleted file mode 100644 index 32e9f41..0000000 --- a/dist/modules/content/getArchiveEntries.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["getArchiveEntries.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nexport type ArchiveEntries> = {\n docs: T[];\n hasNextPage: boolean;\n hasPrevPage: boolean;\n /** 1-based. */\n page: number;\n totalDocs: number;\n totalPages: number;\n};\ntype GetArchiveEntriesArgs = {\n /** Collection to list, e.g. 'posts'. */\n collection: string;\n /** Relationship depth. Defaults to 1 — enough for a cover image. */\n depth?: number;\n locale: string;\n /** 1-based. Values below 1 are clamped. */\n page?: number;\n payload: BasePayload;\n /** Defaults to 10. */\n perPage?: number;\n /** Payload sort string. Defaults to newest first. */\n sort?: string;\n /** Extra constraints merged into the query, e.g. { category: { equals: id } }. */\n where?: Record;\n};\n/**\n * Fetches one page of a collection's entries for an archive listing.\n *\n * Only published documents are returned when the collection has drafts enabled;\n * Payload's `where` on `_status` is left to the caller, since a collection\n * without drafts has no such field.\n *\n * Returns pagination facts rather than markup — the listing itself belongs to\n * the client (as a block on the archive page, most likely), because how a list\n * of posts should look isn't something a plugin can decide.\n */\nexport declare function getArchiveEntries>({ collection, depth, locale, page, payload, perPage, sort, where, }: GetArchiveEntriesArgs): Promise>;\nexport {};\n"],"names":[],"mappings":"AAsCA,WAAU"} \ No newline at end of file diff --git a/dist/modules/content/index.d.js b/dist/modules/content/index.d.js deleted file mode 100644 index 727c705..0000000 --- a/dist/modules/content/index.d.js +++ /dev/null @@ -1,7 +0,0 @@ -export { buildArchiveFields } from './archiveFields.js'; -export { getArchiveEntries } from './getArchiveEntries.js'; -export { buildArchivePath, buildEntryPath, parsePageParam } from './paths.js'; -export { resolveRoute } from './resolveRoute.js'; -export { archiveFieldName } from './types.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/content/index.d.js.map b/dist/modules/content/index.d.js.map deleted file mode 100644 index 56e0f99..0000000 --- a/dist/modules/content/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { buildArchiveFields } from './archiveFields.js';\nexport { getArchiveEntries } from './getArchiveEntries.js';\nexport type { ArchiveEntries } from './getArchiveEntries.js';\nexport { buildArchivePath, buildEntryPath, parsePageParam } from './paths.js';\nexport { resolveRoute } from './resolveRoute.js';\nexport type { ResolvedRoute } from './resolveRoute.js';\nexport type { ContentCollectionOption, ContentOption } from './types.js';\nexport { archiveFieldName } from './types.js';\n"],"names":["buildArchiveFields","getArchiveEntries","buildArchivePath","buildEntryPath","parsePageParam","resolveRoute","archiveFieldName"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,qBAAqB;AACxD,SAASC,iBAAiB,QAAQ,yBAAyB;AAE3D,SAASC,gBAAgB,EAAEC,cAAc,EAAEC,cAAc,QAAQ,aAAa;AAC9E,SAASC,YAAY,QAAQ,oBAAoB;AAGjD,SAASC,gBAAgB,QAAQ,aAAa"} \ No newline at end of file diff --git a/dist/modules/content/paths.d.js b/dist/modules/content/paths.d.js deleted file mode 100644 index e1876fb..0000000 --- a/dist/modules/content/paths.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=paths.d.js.map \ No newline at end of file diff --git a/dist/modules/content/paths.d.js.map b/dist/modules/content/paths.d.js.map deleted file mode 100644 index addb684..0000000 --- a/dist/modules/content/paths.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["paths.d.ts"],"sourcesContent":["type ArchivePathArgs = {\n /** Archive page's slug in this locale, e.g. 'artykuly'. */\n archiveSlug: string;\n locale: string;\n /** 1-based. Page 1 is omitted from the URL. */\n page?: number;\n};\n/**\n * Path to an archive listing: /pl/artykuly, /pl/artykuly?page=2.\n *\n * Pagination goes in the query string rather than the path. A path segment\n * (/pl/artykuly/2) would be ambiguous with an entry slugged \"2\", and the\n * alternative (/pl/artykuly/strona/2) drags in yet another localized segment to\n * configure and translate. Google has understood ?page= for years, and\n * rel=next/prev — the reason people used to prefer path segments — was retired.\n */\nexport declare function buildArchivePath({ archiveSlug, locale, page }: ArchivePathArgs): string;\ntype EntryPathArgs = {\n /** Archive page's slug in this locale, e.g. 'artykuly'. */\n archiveSlug: string;\n /** Entry's slug in this locale, e.g. 'moj-post'. */\n entrySlug: string;\n locale: string;\n};\n/** Path to a single entry: /pl/artykuly/moj-post. */\nexport declare function buildEntryPath({ archiveSlug, entrySlug, locale }: EntryPathArgs): string;\n/**\n * Reads a page number out of a query parameter.\n *\n * Anything that isn't a positive integer is page 1 — `?page=abc`, `?page=-5`,\n * `?page=1.5` and a repeated `?page=1&page=2` all have to resolve to something,\n * and silently showing the first page beats a 500 on a URL a crawler invented.\n */\nexport declare function parsePageParam(value: string | string[] | undefined): number;\nexport {};\n"],"names":[],"mappings":"AAkCA,WAAU"} \ No newline at end of file diff --git a/dist/modules/content/resolveRoute.d.js b/dist/modules/content/resolveRoute.d.js deleted file mode 100644 index b25029e..0000000 --- a/dist/modules/content/resolveRoute.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=resolveRoute.d.js.map \ No newline at end of file diff --git a/dist/modules/content/resolveRoute.d.js.map b/dist/modules/content/resolveRoute.d.js.map deleted file mode 100644 index 4cda8d3..0000000 --- a/dist/modules/content/resolveRoute.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["resolveRoute.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { ContentOption } from './types.js';\nexport type ResolvedRoute = \n/** Locale root — the page assigned as Homepage in System Pages. */\n{\n /** The archive page this entry lives under — its slug is the URL prefix. */\n archive: Record;\n collection: string;\n doc: Record;\n type: 'entry';\n}\n/** An ordinary page. */\n | {\n collection: string;\n doc: Record;\n /** 1-based, from ?page=. */\n page: number;\n perPage: number;\n type: 'archive';\n}\n/** A collection's archive page, e.g. /pl/artykuly. */\n | {\n doc: Record;\n type: 'home';\n}\n/** A single entry, e.g. /pl/artykuly/moj-post. */\n | {\n doc: Record;\n type: 'page';\n};\ntype ResolveRouteArgs = {\n content?: ContentOption;\n locale: string;\n /** Page number from the query string (?page=2). Defaults to 1. */\n page?: number;\n /** Client's Pages collection slug. Defaults to 'pages'. */\n pagesSlug?: string;\n payload: BasePayload;\n /** Route segments after the locale, e.g. ['artykuly', 'moj-post']. */\n segments?: string[];\n /** SiteSettings global slug. Defaults to 'site-settings'. */\n settingsSlug?: string;\n};\n/**\n * Works out what a URL points at: the home page, an ordinary page, a\n * collection's archive, or a single entry.\n *\n * Routing only. An archive result says which collection to list and on which\n * page, but doesn't fetch the entries — that's `getArchiveEntries`, called by\n * whoever actually needs them. Keeping the two apart means listing changes\n * (sorting, filtering, pagination) never touch routing rules, and metadata\n * generation doesn't pay for a query it would discard.\n *\n * The trick is that archive prefixes aren't configured anywhere — they're the\n * slug of whichever page an editor assigned as that collection's archive. So\n * /pl/artykuly and /en/articles come from one assignment, and renaming the page\n * moves the whole section.\n *\n * Resolution order matters: a first segment matching an archive's slug wins\n * over an ordinary page of the same name, because an archive *is* a page and\n * would otherwise shadow its own entries.\n *\n * Depth beyond {archive}/{entry} isn't supported — categories in the path would\n * make canonical and hreflang ambiguous (the same entry reachable under several\n * URLs).\n */\nexport declare function resolveRoute({ content, locale, page, pagesSlug, payload, segments, settingsSlug, }: ResolveRouteArgs): Promise;\nexport {};\n"],"names":[],"mappings":"AAmEA,WAAU"} \ No newline at end of file diff --git a/dist/modules/content/types.d.js b/dist/modules/content/types.d.js deleted file mode 100644 index 7c93c84..0000000 --- a/dist/modules/content/types.d.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * A collection whose entries live under an archive page, e.g. blog posts at - * /pl/artykuly/moj-post. - * - * The collection itself belongs to the client — Payload keeps its schema in - * code, so adding one is always a code change. What this option adds is the - * routing: the plugin exposes an "archive page" assignment in SiteSettings, and - * whichever page an editor picks becomes the URL segment. Rename that page from - * "Artykuły" to "Wpisy" and the path follows, per locale, with no deploy. - */ /** - * Field name holding a collection's archive page in SiteSettings. - * `posts` → `postsArchive`. - */ export { }; - -//# sourceMappingURL=types.d.js.map \ No newline at end of file diff --git a/dist/modules/content/types.d.js.map b/dist/modules/content/types.d.js.map deleted file mode 100644 index f9965ed..0000000 --- a/dist/modules/content/types.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["types.d.ts"],"sourcesContent":["/**\n * A collection whose entries live under an archive page, e.g. blog posts at\n * /pl/artykuly/moj-post.\n *\n * The collection itself belongs to the client — Payload keeps its schema in\n * code, so adding one is always a code change. What this option adds is the\n * routing: the plugin exposes an \"archive page\" assignment in SiteSettings, and\n * whichever page an editor picks becomes the URL segment. Rename that page from\n * \"Artykuły\" to \"Wpisy\" and the path follows, per locale, with no deploy.\n */\nexport type ContentCollectionOption = {\n /** Slug of the client's collection, e.g. 'posts'. */\n slug: string;\n /** Admin label for the archive assignment. Defaults to the slug. */\n label?: string;\n /** Entries per page in listings. Defaults to 10. */\n perPage?: number;\n};\n/**\n * Plugin option wiring archive-backed collections into routing.\n */\nexport type ContentOption = {\n collections: ContentCollectionOption[];\n};\n/**\n * Field name holding a collection's archive page in SiteSettings.\n * `posts` → `postsArchive`.\n */\nexport declare function archiveFieldName(collectionSlug: string): string;\n"],"names":[],"mappings":"AAAA;;;;;;;;;CASC,GAeD;;;CAGC,GACD,WAAyE"} \ No newline at end of file diff --git a/dist/modules/email/index.d.js b/dist/modules/email/index.d.js deleted file mode 100644 index cc59bb6..0000000 --- a/dist/modules/email/index.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { sendEmail } from './sendEmail.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/email/index.d.js.map b/dist/modules/email/index.d.js.map deleted file mode 100644 index bd7cc88..0000000 --- a/dist/modules/email/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { sendEmail } from './sendEmail.js';\nexport type { SendEmailArgs, SendEmailResult } from './sendEmail.js';\n"],"names":["sendEmail"],"mappings":"AAAA,SAASA,SAAS,QAAQ,iBAAiB"} \ No newline at end of file diff --git a/dist/modules/email/panelSmtpAdapter.d.js b/dist/modules/email/panelSmtpAdapter.d.js deleted file mode 100644 index ff104c1..0000000 --- a/dist/modules/email/panelSmtpAdapter.d.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Payload email adapter backed by the SMTP settings in the SiteIntegrations - * global. - * - * Why this exists: Payload builds its email adapter once, at boot, from the - * config — which would normally mean SMTP credentials living in env vars and a - * redeploy to change them. This adapter instead resolves SMTP on every send, so - * an editor can change the mailbox in the admin panel and the next email uses - * it. - * - * Wiring it into the config means `payload.sendEmail` works everywhere — which - * includes the form-builder's own submission emails (the ones an editor - * configures per form under "Emails"). Those go out over the panel's SMTP with - * no extra code. - * - * Boot-time constraints shape two details: - * - `defaultFromAddress` / `defaultFromName` must be returned synchronously, so - * they're placeholders; the real from-address is applied per message below. - * - nodemailer is imported dynamically inside sendEmail, so merely loading the - * Payload config (or running `generate:importmap`) doesn't pull it in. - */ export { }; - -//# sourceMappingURL=panelSmtpAdapter.d.js.map \ No newline at end of file diff --git a/dist/modules/email/panelSmtpAdapter.d.js.map b/dist/modules/email/panelSmtpAdapter.d.js.map deleted file mode 100644 index 55a7436..0000000 --- a/dist/modules/email/panelSmtpAdapter.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["panelSmtpAdapter.d.ts"],"sourcesContent":["import type { PayloadEmailAdapter } from 'payload';\nexport type PanelSmtpAdapterArgs = {\n /**\n * Used only until the panel is filled in — Payload requires a from-address\n * synchronously at boot, before any global can be read. Once SiteIntegrations\n * has an address, it wins.\n */\n fallbackFromAddress?: string;\n fallbackFromName?: string;\n};\n/**\n * Payload email adapter backed by the SMTP settings in the SiteIntegrations\n * global.\n *\n * Why this exists: Payload builds its email adapter once, at boot, from the\n * config — which would normally mean SMTP credentials living in env vars and a\n * redeploy to change them. This adapter instead resolves SMTP on every send, so\n * an editor can change the mailbox in the admin panel and the next email uses\n * it.\n *\n * Wiring it into the config means `payload.sendEmail` works everywhere — which\n * includes the form-builder's own submission emails (the ones an editor\n * configures per form under \"Emails\"). Those go out over the panel's SMTP with\n * no extra code.\n *\n * Boot-time constraints shape two details:\n * - `defaultFromAddress` / `defaultFromName` must be returned synchronously, so\n * they're placeholders; the real from-address is applied per message below.\n * - nodemailer is imported dynamically inside sendEmail, so merely loading the\n * Payload config (or running `generate:importmap`) doesn't pull it in.\n */\nexport declare const panelSmtpAdapter: (args?: PanelSmtpAdapterArgs) => PayloadEmailAdapter;\n"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;;;;;;CAoBC,GACD,WAA4F"} \ No newline at end of file diff --git a/dist/modules/email/sendEmail.d.js b/dist/modules/email/sendEmail.d.js deleted file mode 100644 index c96dc24..0000000 --- a/dist/modules/email/sendEmail.d.js +++ /dev/null @@ -1,3 +0,0 @@ -import 'server-only'; - -//# sourceMappingURL=sendEmail.d.js.map \ No newline at end of file diff --git a/dist/modules/email/sendEmail.d.js.map b/dist/modules/email/sendEmail.d.js.map deleted file mode 100644 index 1ee6c16..0000000 --- a/dist/modules/email/sendEmail.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["sendEmail.d.ts"],"sourcesContent":["import 'server-only';\nimport type { BasePayload } from 'payload';\nexport type SendEmailArgs = {\n /** Override the configured from-address for this message. */\n from?: string;\n /** HTML body. */\n html: string;\n /** Payload instance — used to read SMTP config from SiteIntegrations. */\n payload: BasePayload;\n replyTo?: string;\n subject: string;\n /** Optional plain-text fallback. */\n text?: string;\n to: string | string[];\n};\nexport type SendEmailResult = {\n error: string;\n sent: false;\n} | {\n messageId: string;\n sent: true;\n};\n/**\n * Sends an email using SMTP settings from the SiteIntegrations global.\n *\n * Reads config at call time (not at boot) so editors can change SMTP in the\n * admin panel without a restart — consistent with the plugin's panel-managed\n * model. `server-only` keeps the SMTP password out of any client bundle.\n *\n * Returns a result object rather than throwing, so callers (e.g. form\n * submission) can handle failure without a try/catch and never leak SMTP\n * details to the client.\n */\nexport declare function sendEmail({ from, html, payload, replyTo, subject, text, to, }: SendEmailArgs): Promise;\n"],"names":[],"mappings":"AAAA,OAAO,cAAc"} \ No newline at end of file diff --git a/dist/modules/forms/formsPluginConfig.d.js b/dist/modules/forms/formsPluginConfig.d.js deleted file mode 100644 index 1e18a1b..0000000 --- a/dist/modules/forms/formsPluginConfig.d.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Configures @payloadcms/plugin-form-builder from IPAL's FormsOption. - * - * Provides the form/form-submissions collections and field types. Email - * delivery is intentionally NOT handled here — the plugin's own SMTP-from-panel - * sender (submitForm) does that, so the form-builder's built-in email (which - * needs a Payload email adapter) is left unused. - */ export { }; - -//# sourceMappingURL=formsPluginConfig.d.js.map \ No newline at end of file diff --git a/dist/modules/forms/formsPluginConfig.d.js.map b/dist/modules/forms/formsPluginConfig.d.js.map deleted file mode 100644 index 1f5f356..0000000 --- a/dist/modules/forms/formsPluginConfig.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["formsPluginConfig.d.ts"],"sourcesContent":["import type { Plugin } from 'payload';\nimport type { FormsOption } from './types.js';\n/**\n * Configures @payloadcms/plugin-form-builder from IPAL's FormsOption.\n *\n * Provides the form/form-submissions collections and field types. Email\n * delivery is intentionally NOT handled here — the plugin's own SMTP-from-panel\n * sender (submitForm) does that, so the form-builder's built-in email (which\n * needs a Payload email adapter) is left unused.\n */\nexport declare function buildFormsPlugin(forms: FormsOption): Plugin;\n"],"names":[],"mappings":"AAEA;;;;;;;CAOC,GACD,WAAqE"} \ No newline at end of file diff --git a/dist/modules/forms/index.d.js b/dist/modules/forms/index.d.js deleted file mode 100644 index 311a50f..0000000 --- a/dist/modules/forms/index.d.js +++ /dev/null @@ -1,6 +0,0 @@ -export { buildFormsPlugin } from './formsPluginConfig.js'; -export { checkRateLimit } from './rateLimit.js'; -export { submitForm } from './submitForm.js'; -export { validateSubmission } from './validateSubmission.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/forms/index.d.js.map b/dist/modules/forms/index.d.js.map deleted file mode 100644 index 6607125..0000000 --- a/dist/modules/forms/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { buildFormsPlugin } from './formsPluginConfig.js';\nexport { checkRateLimit } from './rateLimit.js';\nexport type { RateLimitArgs } from './rateLimit.js';\nexport { submitForm } from './submitForm.js';\nexport type { SubmitFormArgs, SubmitFormResult } from './submitForm.js';\nexport type { FormsCollectionOverrides, FormsFieldsOverride, FormsOption } from './types.js';\nexport { validateSubmission } from './validateSubmission.js';\nexport type { FormValidationResult } from './validateSubmission.js';\n"],"names":["buildFormsPlugin","checkRateLimit","submitForm","validateSubmission"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,yBAAyB;AAC1D,SAASC,cAAc,QAAQ,iBAAiB;AAEhD,SAASC,UAAU,QAAQ,kBAAkB;AAG7C,SAASC,kBAAkB,QAAQ,0BAA0B"} \ No newline at end of file diff --git a/dist/modules/forms/rateLimit.d.js b/dist/modules/forms/rateLimit.d.js deleted file mode 100644 index 44e691c..0000000 --- a/dist/modules/forms/rateLimit.d.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Returns true when the request is within the limit, false when it should be - * rejected. A missing key (no IP) is allowed through — better to accept a - * submission than to block everyone behind a proxy that strips the header. - */ export { }; - -//# sourceMappingURL=rateLimit.d.js.map \ No newline at end of file diff --git a/dist/modules/forms/rateLimit.d.js.map b/dist/modules/forms/rateLimit.d.js.map deleted file mode 100644 index b476e6c..0000000 --- a/dist/modules/forms/rateLimit.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["rateLimit.d.ts"],"sourcesContent":["export type RateLimitArgs = {\n /** Identifier to limit on — typically the client IP. */\n key: string;\n /** Max submissions allowed per window. Defaults to 5. */\n max?: number;\n /** Window length in ms. Defaults to 60_000 (one minute). */\n windowMs?: number;\n};\n/**\n * Returns true when the request is within the limit, false when it should be\n * rejected. A missing key (no IP) is allowed through — better to accept a\n * submission than to block everyone behind a proxy that strips the header.\n */\nexport declare function checkRateLimit({ key, max, windowMs }: RateLimitArgs): boolean;\n"],"names":[],"mappings":"AAQA;;;;CAIC,GACD,WAAuF"} \ No newline at end of file diff --git a/dist/modules/forms/submitForm.d.js b/dist/modules/forms/submitForm.d.js deleted file mode 100644 index cad4ef2..0000000 --- a/dist/modules/forms/submitForm.d.js +++ /dev/null @@ -1,3 +0,0 @@ -import 'server-only'; - -//# sourceMappingURL=submitForm.d.js.map \ No newline at end of file diff --git a/dist/modules/forms/submitForm.d.js.map b/dist/modules/forms/submitForm.d.js.map deleted file mode 100644 index 087e061..0000000 --- a/dist/modules/forms/submitForm.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["submitForm.d.ts"],"sourcesContent":["import 'server-only';\nimport type { BasePayload } from 'payload';\nexport type SubmitFormArgs = {\n /** Submitted field data — shape matches the form's fields. */\n data: Record;\n /** Form-builder form ID this submission belongs to. */\n formId: string;\n /** Client IP — used for Turnstile and rate limiting. */\n ip?: string;\n /**\n * Rate limit: max submissions per IP per minute. Defaults to 5.\n * Set to 0 to disable (e.g. when a real limiter sits in front).\n */\n maxPerMinute?: number;\n payload: BasePayload;\n /** Turnstile token; when present it is verified, when absent it is skipped. */\n turnstileToken?: string;\n};\n/**\n * Why a submission failed — a code, never a user-facing string.\n *\n * The plugin knows what went wrong; it deliberately doesn't decide how to say\n * it. The frontend maps these to its own copy, in its own language, and renders\n * whatever component fits — a field error, a toast, a full message. The plugin\n * has no business choosing the wording or the locale.\n *\n * - `rate_limited` — too many submissions from this IP\n * - `turnstile` — bot check failed\n * - `validation` — a field is missing/too long, or unknown keys were sent;\n * `field` and `kind` narrow it down when a specific field is\n * at fault (absent for whole-payload problems like unknown keys)\n * - `not_found` — no form with this id\n * - `error` — persistence failed unexpectedly\n */\nexport type SubmitFailure = {\n /** The offending field's name, when one field is at fault. */\n field?: string;\n /** What was wrong with it. */\n kind?: 'required' | 'too_long' | 'unknown_fields';\n reason: 'validation';\n success: false;\n} | {\n reason: 'error';\n success: false;\n} | {\n reason: 'not_found';\n success: false;\n} | {\n reason: 'rate_limited';\n success: false;\n} | {\n reason: 'turnstile';\n success: false;\n};\nexport type SubmitFormResult = {\n submissionId: number | string;\n success: true;\n} | SubmitFailure;\n/**\n * Handles a form submission end to end: rate limit, verify Turnstile, validate\n * against the form's own schema, then store.\n *\n * The order is cost-ascending on purpose — the cheapest checks reject first, so\n * a flood never reaches Turnstile's network call or the database.\n *\n * Emails aren't sent here. The form-builder sends whatever an editor configured\n * under the form's \"Emails\" tab (form-submissions hook → payload.sendEmail),\n * which goes out over panelSmtpAdapter. Storing the submission is enough.\n *\n * server-only: touches the Turnstile secret.\n */\nexport declare function submitForm({ data, formId, ip, maxPerMinute, payload, turnstileToken, }: SubmitFormArgs): Promise;\n"],"names":[],"mappings":"AAAA,OAAO,cAAc"} \ No newline at end of file diff --git a/dist/modules/forms/types.d.js b/dist/modules/forms/types.d.js deleted file mode 100644 index 57d91a1..0000000 --- a/dist/modules/forms/types.d.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Forms configuration — mirrors the fields a client enables in the - * form-builder plugin. Kept minimal; the plugin passes these through. - */ export { }; - -//# sourceMappingURL=types.d.js.map \ No newline at end of file diff --git a/dist/modules/forms/types.d.js.map b/dist/modules/forms/types.d.js.map deleted file mode 100644 index 3426f21..0000000 --- a/dist/modules/forms/types.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["types.d.ts"],"sourcesContent":["import type { CollectionConfig, Field } from 'payload';\n/**\n * Receives the collection's default fields and returns the final list — add,\n * remove, or reorder. Same shape the form-builder uses.\n */\nexport type FormsFieldsOverride = (args: {\n defaultFields: Field[];\n}) => Field[];\n/**\n * Overrides for a forms-related collection: replace the fields and/or any\n * other collection setting (admin, access, hooks…).\n */\nexport type FormsCollectionOverrides = {\n fields?: FormsFieldsOverride;\n} & Partial>;\n/**\n * Forms configuration — mirrors the fields a client enables in the\n * form-builder plugin. Kept minimal; the plugin passes these through.\n */\nexport type FormsOption = {\n /** Field types available in the form builder. Sensible defaults applied. */\n fields?: {\n checkbox?: boolean;\n email?: boolean;\n message?: boolean;\n number?: boolean;\n payment?: boolean;\n select?: boolean;\n text?: boolean;\n textarea?: boolean;\n };\n /**\n * Override the forms collection. The plugin stays opinion-free about what a\n * form needs beyond its fields — a client that wants, say, a per-form\n * notification address adds it here:\n *\n * formOverrides: {\n * fields: ({ defaultFields }) => [\n * ...defaultFields,\n * { name: 'notificationEmail', type: 'email' },\n * ],\n * }\n */\n formOverrides?: FormsCollectionOverrides;\n /** Override the form-submissions collection (same shape). */\n formSubmissionOverrides?: FormsCollectionOverrides;\n /** Collections a form can redirect to (e.g. ['pages']). */\n redirectRelationships?: string[];\n};\n"],"names":[],"mappings":"AAeA;;;CAGC,GACD,WA6BE"} \ No newline at end of file diff --git a/dist/modules/forms/validateSubmission.d.js b/dist/modules/forms/validateSubmission.d.js deleted file mode 100644 index c22931a..0000000 --- a/dist/modules/forms/validateSubmission.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=validateSubmission.d.js.map \ No newline at end of file diff --git a/dist/modules/forms/validateSubmission.d.js.map b/dist/modules/forms/validateSubmission.d.js.map deleted file mode 100644 index 5e67022..0000000 --- a/dist/modules/forms/validateSubmission.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["validateSubmission.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\n/** A form-builder field, trimmed to what validation needs. */\ntype FormField = {\n blockType?: string;\n label?: string;\n name?: string;\n required?: boolean | null;\n};\ntype FormDoc = {\n fields?: FormField[];\n id: number | string;\n /** Per-form notification address, when the client added the field. */\n notificationEmail?: string;\n title?: string;\n};\n/**\n * Validation outcome — codes, not user-facing strings. The frontend turns these\n * into its own copy (see SubmitFailure in submitForm).\n */\nexport type FormValidationResult = {\n /** Offending field, when a single field is at fault. */\n field?: string;\n kind: 'required' | 'too_long' | 'unknown_fields';\n ok: false;\n reason: 'invalid';\n} | {\n cleaned: Record;\n form: FormDoc;\n ok: true;\n} | {\n ok: false;\n reason: 'not_found';\n};\n/**\n * Checks submitted data against the form's own definition, rather than trusting\n * whatever arrived.\n *\n * The server action is a public endpoint: a caller can skip the rendered form\n * and post arbitrary keys. Without this, unknown fields would be stored,\n * required fields could be missing, and an oversized value could sail through.\n * So we load the form, keep only keys that are real fields, reject when a\n * required one is blank, and cap length.\n *\n * Returns the loaded form on success so the caller doesn't fetch it twice, and\n * a code + offending field on failure so the frontend can point at it.\n */\nexport declare function validateSubmission(payload: BasePayload, formId: string, data: Record): Promise;\nexport {};\n"],"names":[],"mappings":"AA+CA,WAAU"} \ No newline at end of file diff --git a/dist/modules/frontend/createContentHelpers.d.js b/dist/modules/frontend/createContentHelpers.d.js deleted file mode 100644 index dc3727a..0000000 --- a/dist/modules/frontend/createContentHelpers.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=createContentHelpers.d.js.map \ No newline at end of file diff --git a/dist/modules/frontend/createContentHelpers.d.js.map b/dist/modules/frontend/createContentHelpers.d.js.map deleted file mode 100644 index ff48a22..0000000 --- a/dist/modules/frontend/createContentHelpers.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["createContentHelpers.d.ts"],"sourcesContent":["import type { BasePayload, SanitizedConfig } from 'payload';\nimport type { ArchiveEntries, ContentOption, ResolvedRoute } from '../content/index.js';\nimport type { I18nConfig } from '../i18n/index.js';\nimport type { RobotsRules, SitemapEntry } from '../seo/index.js';\ntype CreateContentHelpersArgs = {\n /**\n * Absolute site origin for sitemap/robots URLs. Falls back to\n * NEXT_PUBLIC_SERVER_URL, then to a relative origin (which most crawlers\n * reject, so set one in production).\n */\n baseUrl?: string;\n /**\n * The client's payload config promise (the default export of payload.config).\n * Passed in because the plugin never imports the client's config directly.\n */\n config: Promise | SanitizedConfig;\n /** Archive-backed collections, same value as the plugin option. */\n content?: ContentOption;\n /**\n * i18n config. Required only if you want the ready-made `sitemap` / `robots`\n * handlers — they need the locale list to emit hreflang.\n */\n i18n?: I18nConfig;\n /** Pages collection slug. Defaults to 'pages'. */\n pagesSlug?: string;\n /** SiteSettings global slug. Defaults to 'site-settings'. */\n settingsSlug?: string;\n};\n/**\n * Bundles the per-request data helpers a frontend needs — the same cached\n * wrappers every project was writing by hand (getPayload, settings, locale\n * list, route resolution, archive entries).\n *\n * Everything is wrapped in React `cache()`, so within one request a value is\n * fetched once no matter how many times it's asked for — which matters because\n * Next runs generateMetadata and the page component separately, and both hit\n * these. Crucially the Payload instance is cached *here*, once, so every helper\n * shares it; that's why this is a factory and not loose functions importing a\n * shared module.\n *\n * ```ts\n * // src/lib/content.ts\n * import { createContentHelpers } from 'ipal-kit'\n * import config from '@/payload.config'\n * import { contentConfig } from '@/content.config'\n *\n * export const { getCachedPayload, getSettings, getConfiguredLocales, resolveRoute, getEntries } =\n * createContentHelpers({ config, content: contentConfig })\n * ```\n *\n * `resolveRoute` and `getEntries` are separate on purpose: routing decides what\n * a URL is, fetching gets the listing. Metadata generation needs the first and\n * not the second, and a page component composes them in two obvious lines.\n */\nexport declare function createContentHelpers({ baseUrl, config, content, i18n, pagesSlug, settingsSlug, }: CreateContentHelpersArgs): {\n getCachedPayload: () => Promise;\n getConfiguredLocales: () => Promise;\n getEntries: (collection: string, locale: string, page: number, perPage: number) => Promise;\n getSettings: (locale: string) => Promise;\n resolveRoute: (locale: string, segments: string[] | undefined, page: number) => Promise;\n robots: () => RobotsRules;\n sitemap: () => Promise;\n};\nexport {};\n"],"names":[],"mappings":"AA+DA,WAAU"} \ No newline at end of file diff --git a/dist/modules/frontend/index.d.js b/dist/modules/frontend/index.d.js deleted file mode 100644 index 63add7f..0000000 --- a/dist/modules/frontend/index.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { createContentHelpers } from './createContentHelpers.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/frontend/index.d.js.map b/dist/modules/frontend/index.d.js.map deleted file mode 100644 index 19392b6..0000000 --- a/dist/modules/frontend/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { createContentHelpers } from './createContentHelpers.js';\n"],"names":["createContentHelpers"],"mappings":"AAAA,SAASA,oBAAoB,QAAQ,4BAA4B"} \ No newline at end of file diff --git a/dist/modules/i18n/getLocalizedSlugs.d.js b/dist/modules/i18n/getLocalizedSlugs.d.js deleted file mode 100644 index 5692e77..0000000 --- a/dist/modules/i18n/getLocalizedSlugs.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=getLocalizedSlugs.d.js.map \ No newline at end of file diff --git a/dist/modules/i18n/getLocalizedSlugs.d.js.map b/dist/modules/i18n/getLocalizedSlugs.d.js.map deleted file mode 100644 index 0ce6e55..0000000 --- a/dist/modules/i18n/getLocalizedSlugs.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["getLocalizedSlugs.d.ts"],"sourcesContent":["import type { LocalizedSlugs } from './localizedPath.js';\nimport type { I18nConfig } from './types.js';\n/**\n * A localized field as Payload returns it when queried with `locale: 'all'`:\n * a map of locale code → value.\n */\ntype LocalizedField = Record;\ntype GetLocalizedSlugsArgs = {\n config: I18nConfig;\n /**\n * The document's localized slug field, as returned by Payload with\n * `locale: 'all'` — e.g. { pl: 'strona-glowna', en: 'home' }.\n */\n slugField: LocalizedField | null | undefined;\n};\n/**\n * Normalizes a document's localized slug field into the LocalizedSlugs\n * contract consumed by buildLocalizedPath / switchLocalePath.\n *\n * Pure function — the template fetches the document (payload.findByID with\n * `locale: 'all'`, where the slug field must be `localized: true`) and passes\n * the raw field in. The plugin never touches the database.\n *\n * Keeps only entries whose locale is configured and whose slug is a\n * non-empty string, so callers get a clean, trustworthy map.\n *\n * @example\n * const doc = await payload.findByID({ collection: 'pages', id, locale: 'all' })\n * const slugs = getLocalizedSlugs({ slugField: doc.slug, config })\n * // → { pl: 'strona-glowna', en: 'home' }\n * switchLocalePath({ slugs, targetLocale: 'en', config }) // → '/en'\n */\nexport declare function getLocalizedSlugs({ config, slugField }: GetLocalizedSlugsArgs): LocalizedSlugs;\nexport {};\n"],"names":[],"mappings":"AAiCA,WAAU"} \ No newline at end of file diff --git a/dist/modules/i18n/helpers.d.js b/dist/modules/i18n/helpers.d.js deleted file mode 100644 index 1926a00..0000000 --- a/dist/modules/i18n/helpers.d.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Returns the full locale definition for a given code, or undefined if not found. - */ export { }; - -//# sourceMappingURL=helpers.d.js.map \ No newline at end of file diff --git a/dist/modules/i18n/helpers.d.js.map b/dist/modules/i18n/helpers.d.js.map deleted file mode 100644 index 6f74cba..0000000 --- a/dist/modules/i18n/helpers.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["helpers.d.ts"],"sourcesContent":["import type { I18nConfig, LocaleDefinition } from './types.js';\n/**\n * Returns all configured locale codes.\n */\nexport declare function getLocaleCodes(config: I18nConfig): string[];\n/**\n * Returns the default locale code.\n */\nexport declare function getDefaultLocale(config: I18nConfig): string;\n/**\n * Checks if a string is a valid configured locale code.\n */\nexport declare function isValidLocale(code: string, config: I18nConfig): boolean;\n/**\n * Returns the full locale definition for a given code, or undefined if not found.\n */\nexport declare function getLocaleDefinition(code: string, config: I18nConfig): LocaleDefinition | undefined;\n"],"names":[],"mappings":"AAaA;;CAEC,GACD,WAA4G"} \ No newline at end of file diff --git a/dist/modules/i18n/index.d.js b/dist/modules/i18n/index.d.js deleted file mode 100644 index 7b6f6c6..0000000 --- a/dist/modules/i18n/index.d.js +++ /dev/null @@ -1,9 +0,0 @@ -export { getLocalizedSlugs } from './getLocalizedSlugs.js'; -export { getDefaultLocale, getLocaleCodes, getLocaleDefinition, isValidLocale } from './helpers.js'; -export { createLocaleMiddleware, DEFAULT_MIDDLEWARE_MATCHER } from './localeMiddleware.js'; -export { buildLocalizationConfig } from './localizationConfig.js'; -export { buildLocalizedPath, switchLocalePath } from './localizedPath.js'; -export { LOCALE_COOKIE_NAME, matchAcceptLanguage, negotiateLocale } from './negotiateLocale.js'; -export { validateI18nConfig } from './validation.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/i18n/index.d.js.map b/dist/modules/i18n/index.d.js.map deleted file mode 100644 index 59d02ea..0000000 --- a/dist/modules/i18n/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { getLocalizedSlugs } from './getLocalizedSlugs.js';\nexport { getDefaultLocale, getLocaleCodes, getLocaleDefinition, isValidLocale } from './helpers.js';\nexport { createLocaleMiddleware, DEFAULT_MIDDLEWARE_MATCHER } from './localeMiddleware.js';\nexport type { LocaleMiddlewareResult } from './localeMiddleware.js';\nexport { buildLocalizationConfig } from './localizationConfig.js';\nexport { buildLocalizedPath, switchLocalePath } from './localizedPath.js';\nexport type { LocalizedSlugs } from './localizedPath.js';\nexport { LOCALE_COOKIE_NAME, matchAcceptLanguage, negotiateLocale } from './negotiateLocale.js';\nexport type { I18nConfig, LocaleDefinition } from './types.js';\nexport { validateI18nConfig } from './validation.js';\n"],"names":["getLocalizedSlugs","getDefaultLocale","getLocaleCodes","getLocaleDefinition","isValidLocale","createLocaleMiddleware","DEFAULT_MIDDLEWARE_MATCHER","buildLocalizationConfig","buildLocalizedPath","switchLocalePath","LOCALE_COOKIE_NAME","matchAcceptLanguage","negotiateLocale","validateI18nConfig"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,yBAAyB;AAC3D,SAASC,gBAAgB,EAAEC,cAAc,EAAEC,mBAAmB,EAAEC,aAAa,QAAQ,eAAe;AACpG,SAASC,sBAAsB,EAAEC,0BAA0B,QAAQ,wBAAwB;AAE3F,SAASC,uBAAuB,QAAQ,0BAA0B;AAClE,SAASC,kBAAkB,EAAEC,gBAAgB,QAAQ,qBAAqB;AAE1E,SAASC,kBAAkB,EAAEC,mBAAmB,EAAEC,eAAe,QAAQ,uBAAuB;AAEhG,SAASC,kBAAkB,QAAQ,kBAAkB"} \ No newline at end of file diff --git a/dist/modules/i18n/localeMiddleware.d.js b/dist/modules/i18n/localeMiddleware.d.js deleted file mode 100644 index 127b794..0000000 --- a/dist/modules/i18n/localeMiddleware.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=localeMiddleware.d.js.map \ No newline at end of file diff --git a/dist/modules/i18n/localeMiddleware.d.js.map b/dist/modules/i18n/localeMiddleware.d.js.map deleted file mode 100644 index 14666b2..0000000 --- a/dist/modules/i18n/localeMiddleware.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["localeMiddleware.d.ts"],"sourcesContent":["import type { I18nConfig } from './types.js';\n/**\n * Minimal request shape the middleware reads. Kept structural so the plugin\n * doesn't hard-depend on next/server types; a Next.js `NextRequest` satisfies it.\n */\ntype MiddlewareRequest = {\n cookies: {\n get: (name: string) => {\n value: string;\n } | undefined;\n };\n headers: {\n get: (name: string) => null | string;\n };\n nextUrl: {\n clone: () => URL;\n pathname: string;\n search: string;\n };\n url: string;\n};\n/**\n * What the factory returns — the caller (in Next next-middleware.ts) decides how to\n * act: `redirect` means send a 307 to `location` and set the locale cookie;\n * `next` means let the request pass through untouched.\n */\nexport type LocaleMiddlewareResult = {\n cookie: {\n name: string;\n value: string;\n };\n location: string;\n type: 'redirect';\n} | {\n type: 'next';\n};\ntype CreateLocaleMiddlewareArgs = {\n config: I18nConfig;\n /** Cookie name for the locale choice. Defaults to LOCALE_COOKIE_NAME. */\n cookieName?: string;\n};\n/**\n * Builds locale-routing logic for Next.js middleware.\n *\n * Behavior:\n * - path already starts with a valid locale (/pl/...) → pass through\n * - any other path (/, /o-nas) → redirect to /{locale}{path}, where locale\n * comes from negotiateLocale (cookie → Accept-Language → default)\n * - the chosen locale is written to a cookie so the next visit is stable\n *\n * The plugin returns a decision; the thin next-middleware.ts in the client project\n * turns it into a NextResponse. This keeps all logic in the plugin while\n * respecting that next-middleware.ts must physically live in the client app.\n *\n * @example\n * // next-middleware.ts (client project) — one wiring file, no logic:\n * import { NextResponse } from 'next/server'\n * import { localeMiddleware } from './ipal.middleware' // created from this factory\n * export function middleware(req) {\n * const r = localeMiddleware(req)\n * if (r.type === 'next') return NextResponse.next()\n * const res = NextResponse.redirect(r.location)\n * res.cookies.set(r.cookie.name, r.cookie.value)\n * return res\n * }\n */\nexport declare function createLocaleMiddleware({ config, cookieName, }: CreateLocaleMiddlewareArgs): (request: MiddlewareRequest) => LocaleMiddlewareResult;\n/**\n * Default Next.js middleware matcher: run on everything except API routes, the\n * admin panel, Next internals, and files with an extension (static assets).\n */\nexport declare const DEFAULT_MIDDLEWARE_MATCHER: string[];\nexport {};\n"],"names":[],"mappings":"AAwEA,WAAU"} \ No newline at end of file diff --git a/dist/modules/i18n/localeMiddleware.d.ts b/dist/modules/i18n/localeMiddleware.d.ts index cfc518f..5e92043 100644 --- a/dist/modules/i18n/localeMiddleware.d.ts +++ b/dist/modules/i18n/localeMiddleware.d.ts @@ -20,12 +20,12 @@ type MiddlewareRequest = { url: string; }; /** - * What the factory returns — the caller (in Next next-middleware.ts) decides how to + * What the factory returns — the caller (in Next middleware.ts) decides how to * act: `redirect` means send a 307 to `location` and set the locale cookie; * `next` means let the request pass through untouched. */ export type LocaleMiddlewareResult = { - cookie: { + cookie?: { name: string; value: string; }; @@ -36,6 +36,16 @@ export type LocaleMiddlewareResult = { }; type CreateLocaleMiddlewareArgs = { config: I18nConfig; + /** + * Consent category that gates *persisting* the locale cookie. The locale is + * always detected (routing works regardless), but the choice is only written + * to a cookie once the visitor has consented to this category. Defaults to + * 'functional'. Pass 'necessary' to always persist (treat locale as strictly + * necessary), which restores the pre-consent behaviour. + */ + consentCategory?: 'functional' | 'necessary'; + /** Name of the consent cookie to read. Defaults to CONSENT_COOKIE. */ + consentCookieName?: string; /** Cookie name for the locale choice. Defaults to LOCALE_COOKIE_NAME. */ cookieName?: string; }; @@ -48,23 +58,25 @@ type CreateLocaleMiddlewareArgs = { * comes from negotiateLocale (cookie → Accept-Language → default) * - the chosen locale is written to a cookie so the next visit is stable * - * The plugin returns a decision; the thin next-middleware.ts in the client project + * The plugin returns a decision; the thin middleware.ts in the client project * turns it into a NextResponse. This keeps all logic in the plugin while - * respecting that next-middleware.ts must physically live in the client app. + * respecting that middleware.ts must physically live in the client app. * * @example - * // next-middleware.ts (client project) — one wiring file, no logic: + * // middleware.ts (client project) — one wiring file, no logic: * import { NextResponse } from 'next/server' * import { localeMiddleware } from './ipal.middleware' // created from this factory - * export function middleware(req) { + * export function proxy(req) { * const r = localeMiddleware(req) * if (r.type === 'next') return NextResponse.next() * const res = NextResponse.redirect(r.location) - * res.cookies.set(r.cookie.name, r.cookie.value) + * // cookie is optional: only present when the visitor consented to the + * // gating category (functional by default). Guard before setting. + * if (r.cookie) res.cookies.set(r.cookie.name, r.cookie.value) * return res * } */ -export declare function createLocaleMiddleware({ config, cookieName, }: CreateLocaleMiddlewareArgs): (request: MiddlewareRequest) => LocaleMiddlewareResult; +export declare function createLocaleMiddleware({ config, consentCategory, consentCookieName, cookieName, }: CreateLocaleMiddlewareArgs): (request: MiddlewareRequest) => LocaleMiddlewareResult; /** * Default Next.js middleware matcher: run on everything except API routes, the * admin panel, Next internals, and files with an extension (static assets). diff --git a/dist/modules/i18n/localeMiddleware.js b/dist/modules/i18n/localeMiddleware.js index e251ad4..3ef4b5c 100644 --- a/dist/modules/i18n/localeMiddleware.js +++ b/dist/modules/i18n/localeMiddleware.js @@ -1,3 +1,4 @@ +import { CONSENT_COOKIE, parseConsent } from '../consent/storage.js'; import { isValidLocale, LOCALE_COOKIE_NAME, negotiateLocale } from '../i18n/index.js'; /** * First path segment of a URL pathname, or '' for root. @@ -14,22 +15,24 @@ import { isValidLocale, LOCALE_COOKIE_NAME, negotiateLocale } from '../i18n/inde * comes from negotiateLocale (cookie → Accept-Language → default) * - the chosen locale is written to a cookie so the next visit is stable * - * The plugin returns a decision; the thin next-middleware.ts in the client project + * The plugin returns a decision; the thin middleware.ts in the client project * turns it into a NextResponse. This keeps all logic in the plugin while - * respecting that next-middleware.ts must physically live in the client app. + * respecting that middleware.ts must physically live in the client app. * * @example - * // next-middleware.ts (client project) — one wiring file, no logic: + * // middleware.ts (client project) — one wiring file, no logic: * import { NextResponse } from 'next/server' * import { localeMiddleware } from './ipal.middleware' // created from this factory - * export function middleware(req) { + * export function proxy(req) { * const r = localeMiddleware(req) * if (r.type === 'next') return NextResponse.next() * const res = NextResponse.redirect(r.location) - * res.cookies.set(r.cookie.name, r.cookie.value) + * // cookie is optional: only present when the visitor consented to the + * // gating category (functional by default). Guard before setting. + * if (r.cookie) res.cookies.set(r.cookie.name, r.cookie.value) * return res * } - */ export function createLocaleMiddleware({ config, cookieName = LOCALE_COOKIE_NAME }) { + */ export function createLocaleMiddleware({ config, consentCategory = 'functional', consentCookieName = CONSENT_COOKIE, cookieName = LOCALE_COOKIE_NAME }) { return function localeMiddleware(request) { const { pathname } = request.nextUrl; // Already locale-prefixed → nothing to do @@ -47,13 +50,27 @@ import { isValidLocale, LOCALE_COOKIE_NAME, negotiateLocale } from '../i18n/inde // Redirect to the locale-prefixed path, preserving the rest const url = request.nextUrl.clone(); url.pathname = `/${locale}${pathname === '/' ? '' : pathname}`; + // Persist the locale choice ONLY if the visitor consented to the gating + // category. 'necessary' is always granted, so passing consentCategory: + // 'necessary' always persists. For 'functional' (default), we read the + // consent cookie and only write the locale cookie when functional is true. + // Without consent the locale is still detected each request (routing works), + // it just isn't remembered across visits — which is the whole point of + // gating a functional cookie behind consent. + let mayPersist = consentCategory === 'necessary'; + if (!mayPersist) { + const consent = parseConsent(request.cookies.get(consentCookieName)?.value); + mayPersist = consent?.[consentCategory] === true; + } return { type: 'redirect', - cookie: { - name: cookieName, - value: locale - }, - location: url.toString() + location: url.toString(), + ...mayPersist ? { + cookie: { + name: cookieName, + value: locale + } + } : {} }; }; } diff --git a/dist/modules/i18n/localeMiddleware.js.map b/dist/modules/i18n/localeMiddleware.js.map index de77963..b87332a 100644 --- a/dist/modules/i18n/localeMiddleware.js.map +++ b/dist/modules/i18n/localeMiddleware.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../../src/modules/i18n/localeMiddleware.ts"],"sourcesContent":["import type { I18nConfig } from './types.js'\n\nimport { isValidLocale, LOCALE_COOKIE_NAME, negotiateLocale } from '../i18n/index.js'\n\n/**\n * Minimal request shape the middleware reads. Kept structural so the plugin\n * doesn't hard-depend on next/server types; a Next.js `NextRequest` satisfies it.\n */\ntype MiddlewareRequest = {\n cookies: { get: (name: string) => { value: string } | undefined }\n headers: { get: (name: string) => null | string }\n nextUrl: { clone: () => URL; pathname: string; search: string }\n url: string\n}\n\n/**\n * What the factory returns — the caller (in Next next-middleware.ts) decides how to\n * act: `redirect` means send a 307 to `location` and set the locale cookie;\n * `next` means let the request pass through untouched.\n */\nexport type LocaleMiddlewareResult =\n { cookie: { name: string; value: string }; location: string; type: 'redirect' } | { type: 'next' }\n\ntype CreateLocaleMiddlewareArgs = {\n config: I18nConfig\n /** Cookie name for the locale choice. Defaults to LOCALE_COOKIE_NAME. */\n cookieName?: string\n}\n\n/**\n * First path segment of a URL pathname, or '' for root.\n * '/pl/o-nas' → 'pl', '/o-nas' → 'o-nas', '/' → ''.\n */\nfunction firstSegment(pathname: string): string {\n return pathname.split('/').filter(Boolean)[0] ?? ''\n}\n\n/**\n * Builds locale-routing logic for Next.js middleware.\n *\n * Behavior:\n * - path already starts with a valid locale (/pl/...) → pass through\n * - any other path (/, /o-nas) → redirect to /{locale}{path}, where locale\n * comes from negotiateLocale (cookie → Accept-Language → default)\n * - the chosen locale is written to a cookie so the next visit is stable\n *\n * The plugin returns a decision; the thin next-middleware.ts in the client project\n * turns it into a NextResponse. This keeps all logic in the plugin while\n * respecting that next-middleware.ts must physically live in the client app.\n *\n * @example\n * // next-middleware.ts (client project) — one wiring file, no logic:\n * import { NextResponse } from 'next/server'\n * import { localeMiddleware } from './ipal.middleware' // created from this factory\n * export function middleware(req) {\n * const r = localeMiddleware(req)\n * if (r.type === 'next') return NextResponse.next()\n * const res = NextResponse.redirect(r.location)\n * res.cookies.set(r.cookie.name, r.cookie.value)\n * return res\n * }\n */\nexport function createLocaleMiddleware({\n config,\n cookieName = LOCALE_COOKIE_NAME,\n}: CreateLocaleMiddlewareArgs) {\n return function localeMiddleware(request: MiddlewareRequest): LocaleMiddlewareResult {\n const { pathname } = request.nextUrl\n\n // Already locale-prefixed → nothing to do\n if (isValidLocale(firstSegment(pathname), config)) {\n return { type: 'next' }\n }\n\n // Resolve the locale to use\n const locale = negotiateLocale({\n acceptLanguage: request.headers.get('accept-language'),\n config,\n cookieLocale: request.cookies.get(cookieName)?.value ?? null,\n })\n\n // Redirect to the locale-prefixed path, preserving the rest\n const url = request.nextUrl.clone()\n url.pathname = `/${locale}${pathname === '/' ? '' : pathname}`\n\n return {\n type: 'redirect',\n cookie: { name: cookieName, value: locale },\n location: url.toString(),\n }\n }\n}\n\n/**\n * Default Next.js middleware matcher: run on everything except API routes, the\n * admin panel, Next internals, and files with an extension (static assets).\n */\nexport const DEFAULT_MIDDLEWARE_MATCHER = ['/((?!api|admin|_next|.*\\\\..*).*)']\n"],"names":["isValidLocale","LOCALE_COOKIE_NAME","negotiateLocale","firstSegment","pathname","split","filter","Boolean","createLocaleMiddleware","config","cookieName","localeMiddleware","request","nextUrl","type","locale","acceptLanguage","headers","get","cookieLocale","cookies","value","url","clone","cookie","name","location","toString","DEFAULT_MIDDLEWARE_MATCHER"],"mappings":"AAEA,SAASA,aAAa,EAAEC,kBAAkB,EAAEC,eAAe,QAAQ,mBAAkB;AA2BrF;;;CAGC,GACD,SAASC,aAAaC,QAAgB;IACpC,OAAOA,SAASC,KAAK,CAAC,KAAKC,MAAM,CAACC,QAAQ,CAAC,EAAE,IAAI;AACnD;AAEA;;;;;;;;;;;;;;;;;;;;;;;;CAwBC,GACD,OAAO,SAASC,uBAAuB,EACrCC,MAAM,EACNC,aAAaT,kBAAkB,EACJ;IAC3B,OAAO,SAASU,iBAAiBC,OAA0B;QACzD,MAAM,EAAER,QAAQ,EAAE,GAAGQ,QAAQC,OAAO;QAEpC,0CAA0C;QAC1C,IAAIb,cAAcG,aAAaC,WAAWK,SAAS;YACjD,OAAO;gBAAEK,MAAM;YAAO;QACxB;QAEA,4BAA4B;QAC5B,MAAMC,SAASb,gBAAgB;YAC7Bc,gBAAgBJ,QAAQK,OAAO,CAACC,GAAG,CAAC;YACpCT;YACAU,cAAcP,QAAQQ,OAAO,CAACF,GAAG,CAACR,aAAaW,SAAS;QAC1D;QAEA,4DAA4D;QAC5D,MAAMC,MAAMV,QAAQC,OAAO,CAACU,KAAK;QACjCD,IAAIlB,QAAQ,GAAG,CAAC,CAAC,EAAEW,SAASX,aAAa,MAAM,KAAKA,UAAU;QAE9D,OAAO;YACLU,MAAM;YACNU,QAAQ;gBAAEC,MAAMf;gBAAYW,OAAON;YAAO;YAC1CW,UAAUJ,IAAIK,QAAQ;QACxB;IACF;AACF;AAEA;;;CAGC,GACD,OAAO,MAAMC,6BAA6B;IAAC;CAAmC,CAAA"} \ No newline at end of file +{"version":3,"sources":["../../../src/modules/i18n/localeMiddleware.ts"],"sourcesContent":["import type { I18nConfig } from './types.js'\n\nimport { CONSENT_COOKIE, parseConsent } from '../consent/storage.js'\nimport { isValidLocale, LOCALE_COOKIE_NAME, negotiateLocale } from '../i18n/index.js'\n\n/**\n * Minimal request shape the middleware reads. Kept structural so the plugin\n * doesn't hard-depend on next/server types; a Next.js `NextRequest` satisfies it.\n */\ntype MiddlewareRequest = {\n cookies: { get: (name: string) => { value: string } | undefined }\n headers: { get: (name: string) => null | string }\n nextUrl: { clone: () => URL; pathname: string; search: string }\n url: string\n}\n\n/**\n * What the factory returns — the caller (in Next middleware.ts) decides how to\n * act: `redirect` means send a 307 to `location` and set the locale cookie;\n * `next` means let the request pass through untouched.\n */\nexport type LocaleMiddlewareResult =\n | { cookie?: { name: string; value: string }; location: string; type: 'redirect' }\n | { type: 'next' }\n\ntype CreateLocaleMiddlewareArgs = {\n config: I18nConfig\n /**\n * Consent category that gates *persisting* the locale cookie. The locale is\n * always detected (routing works regardless), but the choice is only written\n * to a cookie once the visitor has consented to this category. Defaults to\n * 'functional'. Pass 'necessary' to always persist (treat locale as strictly\n * necessary), which restores the pre-consent behaviour.\n */\n consentCategory?: 'functional' | 'necessary'\n /** Name of the consent cookie to read. Defaults to CONSENT_COOKIE. */\n consentCookieName?: string\n /** Cookie name for the locale choice. Defaults to LOCALE_COOKIE_NAME. */\n cookieName?: string\n}\n\n/**\n * First path segment of a URL pathname, or '' for root.\n * '/pl/o-nas' → 'pl', '/o-nas' → 'o-nas', '/' → ''.\n */\nfunction firstSegment(pathname: string): string {\n return pathname.split('/').filter(Boolean)[0] ?? ''\n}\n\n/**\n * Builds locale-routing logic for Next.js middleware.\n *\n * Behavior:\n * - path already starts with a valid locale (/pl/...) → pass through\n * - any other path (/, /o-nas) → redirect to /{locale}{path}, where locale\n * comes from negotiateLocale (cookie → Accept-Language → default)\n * - the chosen locale is written to a cookie so the next visit is stable\n *\n * The plugin returns a decision; the thin middleware.ts in the client project\n * turns it into a NextResponse. This keeps all logic in the plugin while\n * respecting that middleware.ts must physically live in the client app.\n *\n * @example\n * // middleware.ts (client project) — one wiring file, no logic:\n * import { NextResponse } from 'next/server'\n * import { localeMiddleware } from './ipal.middleware' // created from this factory\n * export function proxy(req) {\n * const r = localeMiddleware(req)\n * if (r.type === 'next') return NextResponse.next()\n * const res = NextResponse.redirect(r.location)\n * // cookie is optional: only present when the visitor consented to the\n * // gating category (functional by default). Guard before setting.\n * if (r.cookie) res.cookies.set(r.cookie.name, r.cookie.value)\n * return res\n * }\n */\nexport function createLocaleMiddleware({\n config,\n consentCategory = 'functional',\n consentCookieName = CONSENT_COOKIE,\n cookieName = LOCALE_COOKIE_NAME,\n}: CreateLocaleMiddlewareArgs) {\n return function localeMiddleware(request: MiddlewareRequest): LocaleMiddlewareResult {\n const { pathname } = request.nextUrl\n\n // Already locale-prefixed → nothing to do\n if (isValidLocale(firstSegment(pathname), config)) {\n return { type: 'next' }\n }\n\n // Resolve the locale to use\n const locale = negotiateLocale({\n acceptLanguage: request.headers.get('accept-language'),\n config,\n cookieLocale: request.cookies.get(cookieName)?.value ?? null,\n })\n\n // Redirect to the locale-prefixed path, preserving the rest\n const url = request.nextUrl.clone()\n url.pathname = `/${locale}${pathname === '/' ? '' : pathname}`\n\n // Persist the locale choice ONLY if the visitor consented to the gating\n // category. 'necessary' is always granted, so passing consentCategory:\n // 'necessary' always persists. For 'functional' (default), we read the\n // consent cookie and only write the locale cookie when functional is true.\n // Without consent the locale is still detected each request (routing works),\n // it just isn't remembered across visits — which is the whole point of\n // gating a functional cookie behind consent.\n let mayPersist = consentCategory === 'necessary'\n if (!mayPersist) {\n const consent = parseConsent(request.cookies.get(consentCookieName)?.value)\n mayPersist = consent?.[consentCategory] === true\n }\n\n return {\n type: 'redirect',\n location: url.toString(),\n ...(mayPersist ? { cookie: { name: cookieName, value: locale } } : {}),\n }\n }\n}\n\n/**\n * Default Next.js middleware matcher: run on everything except API routes, the\n * admin panel, Next internals, and files with an extension (static assets).\n */\nexport const DEFAULT_MIDDLEWARE_MATCHER = ['/((?!api|admin|_next|.*\\\\..*).*)']\n"],"names":["CONSENT_COOKIE","parseConsent","isValidLocale","LOCALE_COOKIE_NAME","negotiateLocale","firstSegment","pathname","split","filter","Boolean","createLocaleMiddleware","config","consentCategory","consentCookieName","cookieName","localeMiddleware","request","nextUrl","type","locale","acceptLanguage","headers","get","cookieLocale","cookies","value","url","clone","mayPersist","consent","location","toString","cookie","name","DEFAULT_MIDDLEWARE_MATCHER"],"mappings":"AAEA,SAASA,cAAc,EAAEC,YAAY,QAAQ,wBAAuB;AACpE,SAASC,aAAa,EAAEC,kBAAkB,EAAEC,eAAe,QAAQ,mBAAkB;AAsCrF;;;CAGC,GACD,SAASC,aAAaC,QAAgB;IACpC,OAAOA,SAASC,KAAK,CAAC,KAAKC,MAAM,CAACC,QAAQ,CAAC,EAAE,IAAI;AACnD;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BC,GACD,OAAO,SAASC,uBAAuB,EACrCC,MAAM,EACNC,kBAAkB,YAAY,EAC9BC,oBAAoBb,cAAc,EAClCc,aAAaX,kBAAkB,EACJ;IAC3B,OAAO,SAASY,iBAAiBC,OAA0B;QACzD,MAAM,EAAEV,QAAQ,EAAE,GAAGU,QAAQC,OAAO;QAEpC,0CAA0C;QAC1C,IAAIf,cAAcG,aAAaC,WAAWK,SAAS;YACjD,OAAO;gBAAEO,MAAM;YAAO;QACxB;QAEA,4BAA4B;QAC5B,MAAMC,SAASf,gBAAgB;YAC7BgB,gBAAgBJ,QAAQK,OAAO,CAACC,GAAG,CAAC;YACpCX;YACAY,cAAcP,QAAQQ,OAAO,CAACF,GAAG,CAACR,aAAaW,SAAS;QAC1D;QAEA,4DAA4D;QAC5D,MAAMC,MAAMV,QAAQC,OAAO,CAACU,KAAK;QACjCD,IAAIpB,QAAQ,GAAG,CAAC,CAAC,EAAEa,SAASb,aAAa,MAAM,KAAKA,UAAU;QAE9D,wEAAwE;QACxE,uEAAuE;QACvE,uEAAuE;QACvE,2EAA2E;QAC3E,6EAA6E;QAC7E,uEAAuE;QACvE,6CAA6C;QAC7C,IAAIsB,aAAahB,oBAAoB;QACrC,IAAI,CAACgB,YAAY;YACf,MAAMC,UAAU5B,aAAae,QAAQQ,OAAO,CAACF,GAAG,CAACT,oBAAoBY;YACrEG,aAAaC,SAAS,CAACjB,gBAAgB,KAAK;QAC9C;QAEA,OAAO;YACLM,MAAM;YACNY,UAAUJ,IAAIK,QAAQ;YACtB,GAAIH,aAAa;gBAAEI,QAAQ;oBAAEC,MAAMnB;oBAAYW,OAAON;gBAAO;YAAE,IAAI,CAAC,CAAC;QACvE;IACF;AACF;AAEA;;;CAGC,GACD,OAAO,MAAMe,6BAA6B;IAAC;CAAmC,CAAA"} \ No newline at end of file diff --git a/dist/modules/i18n/localizationConfig.d.js b/dist/modules/i18n/localizationConfig.d.js deleted file mode 100644 index a4e7abe..0000000 --- a/dist/modules/i18n/localizationConfig.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=localizationConfig.d.js.map \ No newline at end of file diff --git a/dist/modules/i18n/localizationConfig.d.js.map b/dist/modules/i18n/localizationConfig.d.js.map deleted file mode 100644 index a6810bc..0000000 --- a/dist/modules/i18n/localizationConfig.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["localizationConfig.d.ts"],"sourcesContent":["import type { Config } from 'payload';\nimport type { I18nConfig } from './types.js';\ntype PayloadLocalizationConfig = NonNullable;\n/**\n * Transforms validated i18n config into Payload's localization object.\n * Pure function — no side effects, no validation (caller validates first).\n */\nexport declare function buildLocalizationConfig(config: I18nConfig): PayloadLocalizationConfig;\nexport {};\n"],"names":[],"mappings":"AAQA,WAAU"} \ No newline at end of file diff --git a/dist/modules/i18n/localizedPath.d.js b/dist/modules/i18n/localizedPath.d.js deleted file mode 100644 index 030480a..0000000 --- a/dist/modules/i18n/localizedPath.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=localizedPath.d.js.map \ No newline at end of file diff --git a/dist/modules/i18n/localizedPath.d.js.map b/dist/modules/i18n/localizedPath.d.js.map deleted file mode 100644 index 3fc4571..0000000 --- a/dist/modules/i18n/localizedPath.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["localizedPath.d.ts"],"sourcesContent":["import type { I18nConfig } from './types.js';\n/**\n * Minimal shape the path builder needs from a document.\n *\n * The plugin doesn't know the client's Pages type, so it depends only on\n * this contract: a map of locale code → slug for that locale. The template\n * supplies it (e.g. by reading the localized slug field across locales).\n */\nexport type LocalizedSlugs = Record;\ntype BuildPathArgs = {\n config: I18nConfig;\n /**\n * Slug that represents the site root (served at /{locale} with no trailing\n * segment). Defaults to 'home'. Matched against the slug in the target locale.\n */\n homeSlug?: string;\n /** Target locale to build the path for */\n locale: string;\n /**\n * Localized segment the document lives under, e.g.\n * `{ pl: 'artykuly', en: 'articles' }` → /pl/artykuly/moj-post.\n *\n * These are the slugs of the collection's archive page, so the prefix is\n * whatever an editor named that page — and it differs per locale for free.\n * A document under a prefix is never the home page, so homeSlug is ignored.\n */\n prefix?: LocalizedSlugs;\n /** slug per locale, e.g. { pl: 'strona-glowna', en: 'home' } */\n slugs: LocalizedSlugs;\n};\n/**\n * Builds a locale-prefixed path for a document in a target locale.\n *\n * Always prefixes the locale: /{locale} or /{locale}/{slug}. The home slug\n * collapses to the locale root. Returns undefined if the document has no slug\n * in the target locale (caller decides fallback behavior).\n *\n * @example\n * buildLocalizedPath({ slugs: { pl: 'strona-glowna', en: 'home' }, locale: 'en', config })\n * // → '/en' (home slug collapses to root)\n *\n * buildLocalizedPath({ slugs: { pl: 'o-nas', en: 'about' }, locale: 'en', config })\n * // → '/en/about'\n *\n * buildLocalizedPath({\n * slugs: { pl: 'moj-post', en: 'my-post' },\n * prefix: { pl: 'artykuly', en: 'articles' },\n * locale: 'en',\n * config,\n * })\n * // → '/en/articles/my-post'\n */\nexport declare function buildLocalizedPath({ config, homeSlug, locale, prefix, slugs, }: BuildPathArgs): string | undefined;\ntype SwitchLocaleArgs = {\n config: I18nConfig;\n homeSlug?: string;\n prefix?: LocalizedSlugs;\n slugs: LocalizedSlugs;\n targetLocale: string;\n};\n/**\n * Resolves the equivalent path for the same document in a different locale —\n * the language-switcher use case (/pl/strona-glowna → /en/home).\n *\n * Never dead-ends on a 404. When the document has no slug in the target locale,\n * falls back to the archive it belongs to (/en/articles) if there is one, and\n * to the locale root otherwise — the closest place the visitor would want.\n */\nexport declare function switchLocalePath({ config, homeSlug, prefix, slugs, targetLocale, }: SwitchLocaleArgs): string;\nexport {};\n"],"names":[],"mappings":"AAqEA,WAAU"} \ No newline at end of file diff --git a/dist/modules/i18n/negotiateLocale.d.js b/dist/modules/i18n/negotiateLocale.d.js deleted file mode 100644 index 4bef334..0000000 --- a/dist/modules/i18n/negotiateLocale.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=negotiateLocale.d.js.map \ No newline at end of file diff --git a/dist/modules/i18n/negotiateLocale.d.js.map b/dist/modules/i18n/negotiateLocale.d.js.map deleted file mode 100644 index 8b8714a..0000000 --- a/dist/modules/i18n/negotiateLocale.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["negotiateLocale.d.ts"],"sourcesContent":["import type { I18nConfig } from './types.js';\n/** Cookie name the template uses to persist a visitor's locale choice. */\nexport declare const LOCALE_COOKIE_NAME = \"ipal-locale\";\ntype NegotiateLocaleArgs = {\n /** Raw Accept-Language header value */\n acceptLanguage?: null | string;\n config: I18nConfig;\n /** Value of the locale cookie, if present (from LOCALE_COOKIE_NAME) */\n cookieLocale?: null | string;\n};\n/**\n * Resolves which locale to serve, in priority order:\n * 1. Cookie (explicit prior choice)\n * 2. Accept-Language header (best match against configured locales)\n * 3. Configured default locale\n *\n * Pure function — the template feeds it request data and acts on the result\n * (redirect, cookie set). No Next.js or request objects here.\n */\nexport declare function negotiateLocale({ acceptLanguage, config, cookieLocale, }: NegotiateLocaleArgs): string;\n/**\n * Parses an Accept-Language header and returns the best-matching configured\n * locale, or undefined if none match.\n *\n * Matches on the primary subtag (e.g. \"en-US\" matches configured \"en\"),\n * respecting the header's quality-value ordering.\n */\nexport declare function matchAcceptLanguage(acceptLanguage: null | string | undefined, config: I18nConfig): string | undefined;\nexport {};\n"],"names":[],"mappings":"AA4BA,WAAU"} \ No newline at end of file diff --git a/dist/modules/i18n/types.d.js b/dist/modules/i18n/types.d.js deleted file mode 100644 index 8d20344..0000000 --- a/dist/modules/i18n/types.d.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Single locale definition provided by the client project. - */ /** - * Full i18n configuration passed through plugin options. - */ export { }; - -//# sourceMappingURL=types.d.js.map \ No newline at end of file diff --git a/dist/modules/i18n/types.d.js.map b/dist/modules/i18n/types.d.js.map deleted file mode 100644 index 14c4e7b..0000000 --- a/dist/modules/i18n/types.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["types.d.ts"],"sourcesContent":["/**\n * Single locale definition provided by the client project.\n */\nexport type LocaleDefinition = {\n /** BCP-47 language code, e.g. 'pl', 'en', 'de' */\n code: string;\n /** Human-readable label, e.g. 'Polski', 'English' */\n label: string;\n /** Right-to-left script (defaults to false) */\n rtl?: boolean;\n};\n/**\n * Full i18n configuration passed through plugin options.\n */\nexport type I18nConfig = {\n defaultLocale: string;\n /** Enable locale fallback when content is missing (defaults to true) */\n fallback?: boolean;\n locales: [LocaleDefinition, ...LocaleDefinition[]];\n};\n"],"names":[],"mappings":"AAAA;;CAEC,GASD;;CAEC,GACD,WAKE"} \ No newline at end of file diff --git a/dist/modules/i18n/validation.d.js b/dist/modules/i18n/validation.d.js deleted file mode 100644 index 3699299..0000000 --- a/dist/modules/i18n/validation.d.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Validates i18n config at plugin initialization. - * Throws descriptive errors — fail fast, no silent defaults. - */ export { }; - -//# sourceMappingURL=validation.d.js.map \ No newline at end of file diff --git a/dist/modules/i18n/validation.d.js.map b/dist/modules/i18n/validation.d.js.map deleted file mode 100644 index 838e443..0000000 --- a/dist/modules/i18n/validation.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["validation.d.ts"],"sourcesContent":["import type { I18nConfig } from './types.js';\n/**\n * Validates i18n config at plugin initialization.\n * Throws descriptive errors — fail fast, no silent defaults.\n */\nexport declare function validateI18nConfig(config: I18nConfig): void;\n"],"names":[],"mappings":"AACA;;;CAGC,GACD,WAAqE"} \ No newline at end of file diff --git a/dist/modules/pages/getSystemPagePath.d.js b/dist/modules/pages/getSystemPagePath.d.js deleted file mode 100644 index 1b1542f..0000000 --- a/dist/modules/pages/getSystemPagePath.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=getSystemPagePath.d.js.map \ No newline at end of file diff --git a/dist/modules/pages/getSystemPagePath.d.js.map b/dist/modules/pages/getSystemPagePath.d.js.map deleted file mode 100644 index 47c2f48..0000000 --- a/dist/modules/pages/getSystemPagePath.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["getSystemPagePath.d.ts"],"sourcesContent":["import type { I18nConfig } from '../i18n/index.js';\n/**\n * The shape we need from an assigned system-page document: its localized slug\n * field, as returned by Payload when the parent is read with `locale: 'all'`.\n *\n * The plugin doesn't know the client's Pages type, so it depends only on this\n * minimal contract.\n */\ntype AssignedPage = {\n slug?: null | Record;\n};\ntype GetSystemPagePathArgs = {\n config: I18nConfig;\n /**\n * Slug that represents the site root. Defaults to 'home'. When the assigned\n * page's slug in the target locale equals this, the path collapses to the\n * locale root (/pl, /en).\n */\n homeSlug?: string;\n /** Target locale to build the path for. */\n locale: string;\n /**\n * The resolved system-page assignment from SiteSettings — the related\n * document object (not just an ID), read with `locale: 'all'` so its slug\n * is a locale→value map. Pass null/undefined if the role is unassigned.\n */\n page: AssignedPage | null | undefined;\n};\n/**\n * Resolves a system-page assignment to a locale-aware path.\n *\n * Bridges the Pages module (which document plays a role) and the i18n module\n * (how that document's localized slug becomes a URL). This is what powers\n * \"visit /pl → serve the homepage\": read SiteSettings.homepage, pass the\n * related document here, get /pl/strona-glowna (or /pl if it's the home slug).\n *\n * Returns undefined when the role is unassigned or the assigned page has no\n * slug in the target locale — the caller decides the fallback (e.g. 404,\n * redirect to default locale).\n *\n * @example\n * const settings = await payload.findGlobal({ slug: 'site-settings', locale: 'all', depth: 1 })\n * getSystemPagePath({ page: settings.homepage, locale: 'pl', config })\n * // → '/pl' (home slug collapses to root)\n * getSystemPagePath({ page: settings.privacyPolicy, locale: 'en', config })\n * // → '/en/privacy-policy'\n */\nexport declare function getSystemPagePath({ config, homeSlug, locale, page, }: GetSystemPagePathArgs): string | undefined;\nexport {};\n"],"names":[],"mappings":"AAgDA,WAAU"} \ No newline at end of file diff --git a/dist/modules/pages/index.d.js b/dist/modules/pages/index.d.js deleted file mode 100644 index d145377..0000000 --- a/dist/modules/pages/index.d.js +++ /dev/null @@ -1,5 +0,0 @@ -export { getSystemPagePath } from './getSystemPagePath.js'; -export { buildSystemPagesFields } from './systemPagesFields.js'; -export { ALL_SYSTEM_PAGE_ROLES } from './types.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/pages/index.d.js.map b/dist/modules/pages/index.d.js.map deleted file mode 100644 index 6eb71e9..0000000 --- a/dist/modules/pages/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { getSystemPagePath } from './getSystemPagePath.js';\nexport { buildSystemPagesFields } from './systemPagesFields.js';\nexport type { PagesOption, SystemPageRole } from './types.js';\nexport { ALL_SYSTEM_PAGE_ROLES } from './types.js';\n"],"names":["getSystemPagePath","buildSystemPagesFields","ALL_SYSTEM_PAGE_ROLES"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,yBAAyB;AAC3D,SAASC,sBAAsB,QAAQ,yBAAyB;AAEhE,SAASC,qBAAqB,QAAQ,aAAa"} \ No newline at end of file diff --git a/dist/modules/pages/systemPagesFields.d.js b/dist/modules/pages/systemPagesFields.d.js deleted file mode 100644 index 947a5c4..0000000 --- a/dist/modules/pages/systemPagesFields.d.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Builds one relationship field per configured system-page role. - * - * Each field points at the client's Pages collection (via the provided slug) - * and holds a single document reference. The referenced document's slug is - * localized, so the same assignment resolves to /pl/strona-glowna and - * /en/home at runtime — role assignment is locale-agnostic, path resolution - * is locale-aware (see getSystemPagePath). - */ export { }; - -//# sourceMappingURL=systemPagesFields.d.js.map \ No newline at end of file diff --git a/dist/modules/pages/systemPagesFields.d.js.map b/dist/modules/pages/systemPagesFields.d.js.map deleted file mode 100644 index 263d480..0000000 --- a/dist/modules/pages/systemPagesFields.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["systemPagesFields.d.ts"],"sourcesContent":["import type { Field } from 'payload';\nimport type { PagesOption } from './types.js';\n/**\n * Builds one relationship field per configured system-page role.\n *\n * Each field points at the client's Pages collection (via the provided slug)\n * and holds a single document reference. The referenced document's slug is\n * localized, so the same assignment resolves to /pl/strona-glowna and\n * /en/home at runtime — role assignment is locale-agnostic, path resolution\n * is locale-aware (see getSystemPagePath).\n */\nexport declare function buildSystemPagesFields(pages: PagesOption): Field[];\n"],"names":[],"mappings":"AAEA;;;;;;;;CAQC,GACD,WAA4E"} \ No newline at end of file diff --git a/dist/modules/pages/systemPagesFields.js b/dist/modules/pages/systemPagesFields.js index 8ce13d4..4426845 100644 --- a/dist/modules/pages/systemPagesFields.js +++ b/dist/modules/pages/systemPagesFields.js @@ -2,12 +2,14 @@ import { ALL_SYSTEM_PAGE_ROLES } from './types.js'; /** Admin-facing labels per role. */ const ROLE_LABELS = { cookiePolicy: 'Cookie Policy', homepage: 'Homepage', - privacyPolicy: 'Privacy Policy' + privacyPolicy: 'Privacy Policy', + termsOfService: 'Terms of Service' }; /** Admin descriptions per role. */ const ROLE_DESCRIPTIONS = { cookiePolicy: 'Page linked from the cookie consent banner.', homepage: 'Page served at the locale root (e.g. /pl, /en).', - privacyPolicy: 'Page linked as the privacy policy.' + privacyPolicy: 'Page linked as the privacy policy.', + termsOfService: 'Page linked as the terms of service / site regulations.' }; /** * Builds one relationship field per configured system-page role. diff --git a/dist/modules/pages/systemPagesFields.js.map b/dist/modules/pages/systemPagesFields.js.map index c8cfe91..da8e72b 100644 --- a/dist/modules/pages/systemPagesFields.js.map +++ b/dist/modules/pages/systemPagesFields.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../../src/modules/pages/systemPagesFields.ts"],"sourcesContent":["import type { Field, RelationshipField } from 'payload'\n\nimport type { PagesOption, SystemPageRole } from './types.js'\n\nimport { ALL_SYSTEM_PAGE_ROLES } from './types.js'\n\n/** Admin-facing labels per role. */\nconst ROLE_LABELS: Record = {\n cookiePolicy: 'Cookie Policy',\n homepage: 'Homepage',\n privacyPolicy: 'Privacy Policy',\n}\n\n/** Admin descriptions per role. */\nconst ROLE_DESCRIPTIONS: Record = {\n cookiePolicy: 'Page linked from the cookie consent banner.',\n homepage: 'Page served at the locale root (e.g. /pl, /en).',\n privacyPolicy: 'Page linked as the privacy policy.',\n}\n\n/**\n * Builds one relationship field per configured system-page role.\n *\n * Each field points at the client's Pages collection (via the provided slug)\n * and holds a single document reference. The referenced document's slug is\n * localized, so the same assignment resolves to /pl/strona-glowna and\n * /en/home at runtime — role assignment is locale-agnostic, path resolution\n * is locale-aware (see getSystemPagePath).\n */\nexport function buildSystemPagesFields(pages: PagesOption): Field[] {\n const roles = pages.roles?.length ? pages.roles : [...ALL_SYSTEM_PAGE_ROLES]\n\n return roles.map((role): RelationshipField => ({\n name: role,\n type: 'relationship',\n admin: {\n description: ROLE_DESCRIPTIONS[role],\n },\n label: ROLE_LABELS[role],\n maxDepth: 1,\n relationTo: pages.slug,\n }))\n}\n"],"names":["ALL_SYSTEM_PAGE_ROLES","ROLE_LABELS","cookiePolicy","homepage","privacyPolicy","ROLE_DESCRIPTIONS","buildSystemPagesFields","pages","roles","length","map","role","name","type","admin","description","label","maxDepth","relationTo","slug"],"mappings":"AAIA,SAASA,qBAAqB,QAAQ,aAAY;AAElD,kCAAkC,GAClC,MAAMC,cAA8C;IAClDC,cAAc;IACdC,UAAU;IACVC,eAAe;AACjB;AAEA,iCAAiC,GACjC,MAAMC,oBAAoD;IACxDH,cAAc;IACdC,UAAU;IACVC,eAAe;AACjB;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASE,uBAAuBC,KAAkB;IACvD,MAAMC,QAAQD,MAAMC,KAAK,EAAEC,SAASF,MAAMC,KAAK,GAAG;WAAIR;KAAsB;IAE5E,OAAOQ,MAAME,GAAG,CAAC,CAACC,OAA6B,CAAA;YAC7CC,MAAMD;YACNE,MAAM;YACNC,OAAO;gBACLC,aAAaV,iBAAiB,CAACM,KAAK;YACtC;YACAK,OAAOf,WAAW,CAACU,KAAK;YACxBM,UAAU;YACVC,YAAYX,MAAMY,IAAI;QACxB,CAAA;AACF"} \ No newline at end of file +{"version":3,"sources":["../../../src/modules/pages/systemPagesFields.ts"],"sourcesContent":["import type { Field, RelationshipField } from 'payload'\n\nimport type { PagesOption, SystemPageRole } from './types.js'\n\nimport { ALL_SYSTEM_PAGE_ROLES } from './types.js'\n\n/** Admin-facing labels per role. */\nconst ROLE_LABELS: Record = {\n cookiePolicy: 'Cookie Policy',\n homepage: 'Homepage',\n privacyPolicy: 'Privacy Policy',\n termsOfService: 'Terms of Service',\n}\n\n/** Admin descriptions per role. */\nconst ROLE_DESCRIPTIONS: Record = {\n cookiePolicy: 'Page linked from the cookie consent banner.',\n homepage: 'Page served at the locale root (e.g. /pl, /en).',\n privacyPolicy: 'Page linked as the privacy policy.',\n termsOfService: 'Page linked as the terms of service / site regulations.',\n}\n\n/**\n * Builds one relationship field per configured system-page role.\n *\n * Each field points at the client's Pages collection (via the provided slug)\n * and holds a single document reference. The referenced document's slug is\n * localized, so the same assignment resolves to /pl/strona-glowna and\n * /en/home at runtime — role assignment is locale-agnostic, path resolution\n * is locale-aware (see getSystemPagePath).\n */\nexport function buildSystemPagesFields(pages: PagesOption): Field[] {\n const roles = pages.roles?.length ? pages.roles : [...ALL_SYSTEM_PAGE_ROLES]\n\n return roles.map((role): RelationshipField => ({\n name: role,\n type: 'relationship',\n admin: {\n description: ROLE_DESCRIPTIONS[role],\n },\n label: ROLE_LABELS[role],\n maxDepth: 1,\n relationTo: pages.slug,\n }))\n}\n"],"names":["ALL_SYSTEM_PAGE_ROLES","ROLE_LABELS","cookiePolicy","homepage","privacyPolicy","termsOfService","ROLE_DESCRIPTIONS","buildSystemPagesFields","pages","roles","length","map","role","name","type","admin","description","label","maxDepth","relationTo","slug"],"mappings":"AAIA,SAASA,qBAAqB,QAAQ,aAAY;AAElD,kCAAkC,GAClC,MAAMC,cAA8C;IAClDC,cAAc;IACdC,UAAU;IACVC,eAAe;IACfC,gBAAgB;AAClB;AAEA,iCAAiC,GACjC,MAAMC,oBAAoD;IACxDJ,cAAc;IACdC,UAAU;IACVC,eAAe;IACfC,gBAAgB;AAClB;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASE,uBAAuBC,KAAkB;IACvD,MAAMC,QAAQD,MAAMC,KAAK,EAAEC,SAASF,MAAMC,KAAK,GAAG;WAAIT;KAAsB;IAE5E,OAAOS,MAAME,GAAG,CAAC,CAACC,OAA6B,CAAA;YAC7CC,MAAMD;YACNE,MAAM;YACNC,OAAO;gBACLC,aAAaV,iBAAiB,CAACM,KAAK;YACtC;YACAK,OAAOhB,WAAW,CAACW,KAAK;YACxBM,UAAU;YACVC,YAAYX,MAAMY,IAAI;QACxB,CAAA;AACF"} \ No newline at end of file diff --git a/dist/modules/pages/types.d.js b/dist/modules/pages/types.d.js deleted file mode 100644 index 3b4a70d..0000000 --- a/dist/modules/pages/types.d.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Built-in "system page" roles — documents from the client's Pages - * collection that the site references by function rather than by slug. - */ /** - * Plugin option enabling system-page assignments in SiteSettings. - * - * The plugin doesn't own the Pages collection — the client creates it in - * their own project. This option hands the plugin the collection's slug so - * it can build relationship fields pointing at it. No hardcoding: the slug - * always comes from the client. - */ export { }; - -//# sourceMappingURL=types.d.js.map \ No newline at end of file diff --git a/dist/modules/pages/types.d.js.map b/dist/modules/pages/types.d.js.map deleted file mode 100644 index 28b5c46..0000000 --- a/dist/modules/pages/types.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["types.d.ts"],"sourcesContent":["/**\n * Built-in \"system page\" roles — documents from the client's Pages\n * collection that the site references by function rather than by slug.\n */\nexport type SystemPageRole = 'cookiePolicy' | 'homepage' | 'privacyPolicy';\n/**\n * All system roles in a stable order (used when no subset is configured).\n */\nexport declare const ALL_SYSTEM_PAGE_ROLES: readonly SystemPageRole[];\n/**\n * Plugin option enabling system-page assignments in SiteSettings.\n *\n * The plugin doesn't own the Pages collection — the client creates it in\n * their own project. This option hands the plugin the collection's slug so\n * it can build relationship fields pointing at it. No hardcoding: the slug\n * always comes from the client.\n */\nexport type PagesOption = {\n /**\n * Which system roles to expose as assignable fields.\n * Defaults to all roles when omitted.\n */\n roles?: SystemPageRole[];\n /** Slug of the client's Pages collection, e.g. 'pages'. */\n slug: string;\n};\n"],"names":[],"mappings":"AAAA;;;CAGC,GAMD;;;;;;;CAOC,GACD,WAQE"} \ No newline at end of file diff --git a/dist/modules/pages/types.d.ts b/dist/modules/pages/types.d.ts index 9b62a00..fe3ed3f 100644 --- a/dist/modules/pages/types.d.ts +++ b/dist/modules/pages/types.d.ts @@ -2,7 +2,7 @@ * Built-in "system page" roles — documents from the client's Pages * collection that the site references by function rather than by slug. */ -export type SystemPageRole = 'cookiePolicy' | 'homepage' | 'privacyPolicy'; +export type SystemPageRole = 'cookiePolicy' | 'homepage' | 'privacyPolicy' | 'termsOfService'; /** * All system roles in a stable order (used when no subset is configured). */ diff --git a/dist/modules/pages/types.js b/dist/modules/pages/types.js index c29e5d6..cd81089 100644 --- a/dist/modules/pages/types.js +++ b/dist/modules/pages/types.js @@ -6,7 +6,8 @@ */ export const ALL_SYSTEM_PAGE_ROLES = [ 'homepage', 'privacyPolicy', - 'cookiePolicy' + 'cookiePolicy', + 'termsOfService' ]; //# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/dist/modules/pages/types.js.map b/dist/modules/pages/types.js.map index ae8ef81..9011940 100644 --- a/dist/modules/pages/types.js.map +++ b/dist/modules/pages/types.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../../src/modules/pages/types.ts"],"sourcesContent":["/**\n * Built-in \"system page\" roles — documents from the client's Pages\n * collection that the site references by function rather than by slug.\n */\nexport type SystemPageRole = 'cookiePolicy' | 'homepage' | 'privacyPolicy'\n\n/**\n * All system roles in a stable order (used when no subset is configured).\n */\nexport const ALL_SYSTEM_PAGE_ROLES: readonly SystemPageRole[] = [\n 'homepage',\n 'privacyPolicy',\n 'cookiePolicy',\n]\n\n/**\n * Plugin option enabling system-page assignments in SiteSettings.\n *\n * The plugin doesn't own the Pages collection — the client creates it in\n * their own project. This option hands the plugin the collection's slug so\n * it can build relationship fields pointing at it. No hardcoding: the slug\n * always comes from the client.\n */\nexport type PagesOption = {\n /**\n * Which system roles to expose as assignable fields.\n * Defaults to all roles when omitted.\n */\n roles?: SystemPageRole[]\n /** Slug of the client's Pages collection, e.g. 'pages'. */\n slug: string\n}\n"],"names":["ALL_SYSTEM_PAGE_ROLES"],"mappings":"AAAA;;;CAGC,GAGD;;CAEC,GACD,OAAO,MAAMA,wBAAmD;IAC9D;IACA;IACA;CACD,CAAA"} \ No newline at end of file +{"version":3,"sources":["../../../src/modules/pages/types.ts"],"sourcesContent":["/**\n * Built-in \"system page\" roles — documents from the client's Pages\n * collection that the site references by function rather than by slug.\n */\nexport type SystemPageRole = 'cookiePolicy' | 'homepage' | 'privacyPolicy' | 'termsOfService'\n\n/**\n * All system roles in a stable order (used when no subset is configured).\n */\nexport const ALL_SYSTEM_PAGE_ROLES: readonly SystemPageRole[] = [\n 'homepage',\n 'privacyPolicy',\n 'cookiePolicy',\n 'termsOfService',\n]\n\n/**\n * Plugin option enabling system-page assignments in SiteSettings.\n *\n * The plugin doesn't own the Pages collection — the client creates it in\n * their own project. This option hands the plugin the collection's slug so\n * it can build relationship fields pointing at it. No hardcoding: the slug\n * always comes from the client.\n */\nexport type PagesOption = {\n /**\n * Which system roles to expose as assignable fields.\n * Defaults to all roles when omitted.\n */\n roles?: SystemPageRole[]\n /** Slug of the client's Pages collection, e.g. 'pages'. */\n slug: string\n}\n"],"names":["ALL_SYSTEM_PAGE_ROLES"],"mappings":"AAAA;;;CAGC,GAGD;;CAEC,GACD,OAAO,MAAMA,wBAAmD;IAC9D;IACA;IACA;IACA;CACD,CAAA"} \ No newline at end of file diff --git a/dist/modules/payload/getGlobal.d.js b/dist/modules/payload/getGlobal.d.js deleted file mode 100644 index ef9988a..0000000 --- a/dist/modules/payload/getGlobal.d.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Thin wrapper over payload.findGlobal that keeps locale/depth handling in one - * place. The plugin never calls getPayload itself — the caller passes the - * instance (from getPayload in their app, or req.payload in a hook), matching - * the plugin's data-access rule: logic here, instance from outside. - */ export { }; - -//# sourceMappingURL=getGlobal.d.js.map \ No newline at end of file diff --git a/dist/modules/payload/getGlobal.d.js.map b/dist/modules/payload/getGlobal.d.js.map deleted file mode 100644 index c6e0f85..0000000 --- a/dist/modules/payload/getGlobal.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["getGlobal.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\n/** Locale argument accepted by the global helpers. */\nexport type GlobalQueryOptions = {\n /** Relationship population depth. Defaults to Payload's config default. */\n depth?: number;\n /** Locale to fetch, or 'all' for every locale's values. Defaults to Payload's default. */\n locale?: string;\n};\n/**\n * Thin wrapper over payload.findGlobal that keeps locale/depth handling in one\n * place. The plugin never calls getPayload itself — the caller passes the\n * instance (from getPayload in their app, or req.payload in a hook), matching\n * the plugin's data-access rule: logic here, instance from outside.\n */\nexport declare function getGlobal>(payload: BasePayload, slug: string, options?: GlobalQueryOptions): Promise;\n"],"names":[],"mappings":"AAQA;;;;;CAKC,GACD,WAA6I"} \ No newline at end of file diff --git a/dist/modules/payload/getSiteIntegrations.d.js b/dist/modules/payload/getSiteIntegrations.d.js deleted file mode 100644 index a952372..0000000 --- a/dist/modules/payload/getSiteIntegrations.d.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Fetches the SiteIntegrations global. - * - * This global is admin-only through access control, but the Local API bypasses - * access control by default (overrideAccess: true), so server-side callers get - * the secrets they need (SMTP password, Turnstile secret, R2 keys). Never - * expose the raw result to the client — read the specific values you need - * server-side and pass only what's safe to the browser. - * - * Generic over the return type so the client can pass their generated - * `SiteIntegration` type. - * - * @example - * import type { SiteIntegration } from '@/payload-types' - * const integrations = await getSiteIntegrations(payload) - */ export { }; - -//# sourceMappingURL=getSiteIntegrations.d.js.map \ No newline at end of file diff --git a/dist/modules/payload/getSiteIntegrations.d.js.map b/dist/modules/payload/getSiteIntegrations.d.js.map deleted file mode 100644 index 401c9e2..0000000 --- a/dist/modules/payload/getSiteIntegrations.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["getSiteIntegrations.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { GlobalQueryOptions } from './getGlobal.js';\n/** Slug of the SiteIntegrations global defined by the plugin. */\nexport declare const SITE_INTEGRATIONS_SLUG = \"site-integrations\";\n/**\n * Fetches the SiteIntegrations global.\n *\n * This global is admin-only through access control, but the Local API bypasses\n * access control by default (overrideAccess: true), so server-side callers get\n * the secrets they need (SMTP password, Turnstile secret, R2 keys). Never\n * expose the raw result to the client — read the specific values you need\n * server-side and pass only what's safe to the browser.\n *\n * Generic over the return type so the client can pass their generated\n * `SiteIntegration` type.\n *\n * @example\n * import type { SiteIntegration } from '@/payload-types'\n * const integrations = await getSiteIntegrations(payload)\n */\nexport declare function getSiteIntegrations>(payload: BasePayload, options?: GlobalQueryOptions): Promise;\n"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;CAeC,GACD,WAAyI"} \ No newline at end of file diff --git a/dist/modules/payload/getSiteSettings.d.js b/dist/modules/payload/getSiteSettings.d.js deleted file mode 100644 index 8e9a9d1..0000000 --- a/dist/modules/payload/getSiteSettings.d.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Fetches the SiteSettings global. - * - * Generic over the return type so the client can pass their generated - * `SiteSetting` type for full type safety, while still working without it. - * - * @example - * import type { SiteSetting } from '@/payload-types' - * const settings = await getSiteSettings(payload, { locale: 'pl' }) - */ export { }; - -//# sourceMappingURL=getSiteSettings.d.js.map \ No newline at end of file diff --git a/dist/modules/payload/getSiteSettings.d.js.map b/dist/modules/payload/getSiteSettings.d.js.map deleted file mode 100644 index c67b4be..0000000 --- a/dist/modules/payload/getSiteSettings.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["getSiteSettings.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { GlobalQueryOptions } from './getGlobal.js';\n/** Slug of the SiteSettings global defined by the plugin. */\nexport declare const SITE_SETTINGS_SLUG = \"site-settings\";\n/**\n * Fetches the SiteSettings global.\n *\n * Generic over the return type so the client can pass their generated\n * `SiteSetting` type for full type safety, while still working without it.\n *\n * @example\n * import type { SiteSetting } from '@/payload-types'\n * const settings = await getSiteSettings(payload, { locale: 'pl' })\n */\nexport declare function getSiteSettings>(payload: BasePayload, options?: GlobalQueryOptions): Promise;\n"],"names":[],"mappings":"AAIA;;;;;;;;;CASC,GACD,WAAqI"} \ No newline at end of file diff --git a/dist/modules/payload/index.d.js b/dist/modules/payload/index.d.js deleted file mode 100644 index ec52723..0000000 --- a/dist/modules/payload/index.d.js +++ /dev/null @@ -1,5 +0,0 @@ -export { getGlobal } from './getGlobal.js'; -export { getSiteIntegrations, SITE_INTEGRATIONS_SLUG } from './getSiteIntegrations.js'; -export { getSiteSettings, SITE_SETTINGS_SLUG } from './getSiteSettings.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/payload/index.d.js.map b/dist/modules/payload/index.d.js.map deleted file mode 100644 index 852a1bb..0000000 --- a/dist/modules/payload/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export type { GlobalQueryOptions } from './getGlobal.js';\nexport { getGlobal } from './getGlobal.js';\nexport { getSiteIntegrations, SITE_INTEGRATIONS_SLUG } from './getSiteIntegrations.js';\nexport { getSiteSettings, SITE_SETTINGS_SLUG } from './getSiteSettings.js';\n"],"names":["getGlobal","getSiteIntegrations","SITE_INTEGRATIONS_SLUG","getSiteSettings","SITE_SETTINGS_SLUG"],"mappings":"AACA,SAASA,SAAS,QAAQ,iBAAiB;AAC3C,SAASC,mBAAmB,EAAEC,sBAAsB,QAAQ,2BAA2B;AACvF,SAASC,eAAe,EAAEC,kBAAkB,QAAQ,uBAAuB"} \ No newline at end of file diff --git a/dist/modules/seo/autoFillMeta.d.js b/dist/modules/seo/autoFillMeta.d.js deleted file mode 100644 index 4a1aea6..0000000 --- a/dist/modules/seo/autoFillMeta.d.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Builds a beforeChange hook that fills empty SEO meta fields from document - * content. Only fills when the meta field is blank — never overwrites what an - * editor typed. This runs server-side on every create/update, so editors get - * sensible meta without clicking "auto-generate". - * - * The plugin doesn't know the client's collection shape, so the field mapping - * is configurable; defaults follow the website template. - */ export { }; - -//# sourceMappingURL=autoFillMeta.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/autoFillMeta.d.js.map b/dist/modules/seo/autoFillMeta.d.js.map deleted file mode 100644 index 3354528..0000000 --- a/dist/modules/seo/autoFillMeta.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["autoFillMeta.d.ts"],"sourcesContent":["import type { CollectionBeforeChangeHook } from 'payload';\n/**\n * Maps document fields to SEO meta fields for auto-fill.\n * Defaults match the Payload website template (title → meta.title).\n */\nexport type AutoFillMapping = {\n /** Document field used to fill meta.description when empty. */\n description?: string;\n /** Document field used to fill meta.title when empty. Default: 'title'. */\n title?: string;\n};\n/**\n * Builds a beforeChange hook that fills empty SEO meta fields from document\n * content. Only fills when the meta field is blank — never overwrites what an\n * editor typed. This runs server-side on every create/update, so editors get\n * sensible meta without clicking \"auto-generate\".\n *\n * The plugin doesn't know the client's collection shape, so the field mapping\n * is configurable; defaults follow the website template.\n */\nexport declare function buildAutoFillMetaHook(mapping?: AutoFillMapping): CollectionBeforeChangeHook;\n"],"names":[],"mappings":"AAWA;;;;;;;;CAQC,GACD,WAAqG"} \ No newline at end of file diff --git a/dist/modules/seo/buildMetadata.d.js b/dist/modules/seo/buildMetadata.d.js deleted file mode 100644 index 57039d2..0000000 --- a/dist/modules/seo/buildMetadata.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=buildMetadata.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/buildMetadata.d.js.map b/dist/modules/seo/buildMetadata.d.js.map deleted file mode 100644 index 6cdc909..0000000 --- a/dist/modules/seo/buildMetadata.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["buildMetadata.d.ts"],"sourcesContent":["import type { I18nConfig, LocalizedSlugs } from '../i18n/index.js';\nimport type { TitleOrder } from './composeTitle.js';\nimport type { SeoMeta } from './types.js';\n/**\n * Subset of Next.js `Metadata` this helper produces. Kept local so the plugin\n * doesn't depend on `next` types; the shape is assignable to Next's Metadata.\n */\nexport type PageMetadata = {\n alternates?: {\n canonical?: string;\n languages?: Record;\n };\n description?: string;\n openGraph?: {\n description?: string;\n images?: {\n url: string;\n }[];\n locale?: string;\n title: string;\n };\n title: string;\n};\ntype BuildMetadataArgs = {\n /** Absolute site origin, e.g. 'https://example.com'. */\n baseUrl?: string;\n config: I18nConfig;\n /** Home slug that collapses to the locale root. Defaults to 'home'. */\n homeSlug?: string;\n /** Resolved OG image URL (page image or site defaultShareImage). */\n imageUrl?: null | string;\n /** Current locale being rendered. */\n locale: string;\n /** SEO meta from the document (plugin-seo group). */\n meta?: null | SeoMeta;\n /** Page title or site name first. Defaults to 'page-first'. */\n order?: TitleOrder;\n /**\n * Localized segment the document lives under (an archive page's slugs).\n * Feeds both canonical and hreflang, so /pl/artykuly/moj-post and\n * /en/articles/my-post point at each other correctly.\n */\n prefix?: LocalizedSlugs;\n /**\n * Query string appended to canonical and every hreflang, e.g. '?page=2'.\n *\n * A paginated listing must be canonical to itself — pointing page 2 at page 1\n * tells Google the entries on it don't exist. Alternates carry the same page,\n * since /pl/artykuly?page=2 corresponds to /en/articles?page=2.\n */\n query?: string;\n /** Separator between page title and site name. Defaults to ' | '. */\n separator?: string;\n /** Site name for title composition and OG. */\n siteName?: null | string;\n /** slug per locale for this document — drives canonical + hreflang. */\n slugs: LocalizedSlugs;\n};\n/**\n * Assembles a Next.js-compatible Metadata object from document SEO fields and\n * site-level data. Locale-aware: canonical points at the current locale's\n * path, and hreflang alternates cover every locale the document exists in.\n *\n * Designed for use inside Next.js `generateMetadata`. The caller resolves the\n * pieces (meta group, site name, image URL, localized slugs) and passes them\n * in — the plugin composes, it doesn't fetch.\n */\nexport declare function buildMetadata({ baseUrl, config, homeSlug, imageUrl, locale, meta, order, prefix, query, separator, siteName, slugs, }: BuildMetadataArgs): PageMetadata;\nexport {};\n"],"names":[],"mappings":"AAoEA,WAAU"} \ No newline at end of file diff --git a/dist/modules/seo/buildRobots.d.js b/dist/modules/seo/buildRobots.d.js deleted file mode 100644 index da4c12c..0000000 --- a/dist/modules/seo/buildRobots.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=buildRobots.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/buildRobots.d.js.map b/dist/modules/seo/buildRobots.d.js.map deleted file mode 100644 index de11dd2..0000000 --- a/dist/modules/seo/buildRobots.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["buildRobots.d.ts"],"sourcesContent":["type BuildRobotsArgs = {\n /** Absolute origin, e.g. 'https://example.com'. */\n baseUrl: string;\n /** Paths to disallow. Defaults to Payload's admin and API. */\n disallow?: string[];\n /** Whether to advertise the sitemap. Defaults to true. */\n sitemap?: boolean;\n};\n/**\n * Shape for Next's `app/robots.ts`.\n */\nexport type RobotsRules = {\n host?: string;\n rules: {\n allow?: string;\n disallow?: string[];\n userAgent: string;\n };\n sitemap?: string;\n};\n/**\n * Builds robots rules that allow crawling everything except the admin panel and\n * API, and point crawlers at the sitemap.\n *\n * ```ts\n * // app/robots.ts\n * export default function robots() {\n * return buildRobots({ baseUrl: process.env.NEXT_PUBLIC_SERVER_URL! })\n * }\n * ```\n *\n * The admin and API are disallowed by default — no reason for them in the index,\n * and it keeps crawl budget on real content.\n */\nexport declare function buildRobots({ baseUrl, disallow, sitemap, }: BuildRobotsArgs): RobotsRules;\nexport {};\n"],"names":[],"mappings":"AAmCA,WAAU"} \ No newline at end of file diff --git a/dist/modules/seo/buildSitemapEntries.d.js b/dist/modules/seo/buildSitemapEntries.d.js deleted file mode 100644 index a315fd7..0000000 --- a/dist/modules/seo/buildSitemapEntries.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=buildSitemapEntries.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/buildSitemapEntries.d.js.map b/dist/modules/seo/buildSitemapEntries.d.js.map deleted file mode 100644 index ba4feab..0000000 --- a/dist/modules/seo/buildSitemapEntries.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["buildSitemapEntries.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { ContentOption } from '../content/index.js';\nimport type { I18nConfig } from '../i18n/index.js';\n/**\n * One sitemap entry, shaped for Next's `app/sitemap.ts`.\n *\n * `alternates.languages` is the important part for a multilingual site: Next\n * renders it as `` per URL, which is\n * exactly what Google uses to connect language versions. A sitemap without it\n * is the common, weaker kind.\n */\nexport type SitemapEntry = {\n alternates?: {\n languages: Record;\n };\n changeFrequency?: 'always' | 'daily' | 'hourly' | 'monthly' | 'never' | 'weekly' | 'yearly';\n lastModified?: Date | string;\n priority?: number;\n url: string;\n};\ntype BuildSitemapArgs = {\n /** Absolute origin, e.g. 'https://example.com'. Required for valid sitemap URLs. */\n baseUrl: string;\n changeFrequency?: SitemapEntry['changeFrequency'];\n config: I18nConfig;\n /** Archive-backed collections, same value as the plugin option. */\n content?: ContentOption;\n /**\n * Slug of the page that is the site root (collapses to /{locale}).\n * Read from System Pages when omitted.\n */\n homeSlug?: string;\n /** Pages collection slug. Defaults to 'pages'. */\n pagesSlug?: string;\n payload: BasePayload;\n /** SiteSettings global slug. Defaults to 'site-settings'. */\n settingsSlug?: string;\n};\n/**\n * Collects every public URL — pages and archive entries — as sitemap entries\n * with per-URL hreflang and lastmod.\n *\n * Reuses the same path/hreflang builders as page metadata, so the sitemap can't\n * drift from what the pages actually render (a classic source of sitemap bugs:\n * a URL listed one way and served another). Drafts and noindex documents are\n * omitted.\n *\n * ```ts\n * // app/sitemap.ts\n * export default async function sitemap() {\n * return buildSitemapEntries({\n * payload: await getPayload({ config }),\n * config: i18nConfig,\n * baseUrl: process.env.NEXT_PUBLIC_SERVER_URL!,\n * content: contentConfig,\n * })\n * }\n * ```\n */\nexport declare function buildSitemapEntries({ baseUrl, changeFrequency, config, content, homeSlug, pagesSlug, payload, settingsSlug, }: BuildSitemapArgs): Promise;\nexport {};\n"],"names":[],"mappings":"AA4DA,WAAU"} \ No newline at end of file diff --git a/dist/modules/seo/composeTitle.d.js b/dist/modules/seo/composeTitle.d.js deleted file mode 100644 index 71b8d29..0000000 --- a/dist/modules/seo/composeTitle.d.js +++ /dev/null @@ -1,3 +0,0 @@ -/** Which part comes first in a composed title. */ export { }; - -//# sourceMappingURL=composeTitle.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/composeTitle.d.js.map b/dist/modules/seo/composeTitle.d.js.map deleted file mode 100644 index 8271494..0000000 --- a/dist/modules/seo/composeTitle.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["composeTitle.d.ts"],"sourcesContent":["/** Which part comes first in a composed title. */\nexport type TitleOrder = 'page-first' | 'site-first';\ntype ComposeTitleArgs = {\n /** Defaults to 'page-first' — the page title is what a visitor scans for. */\n order?: TitleOrder;\n /** Page-specific title, e.g. 'About Us'. */\n pageTitle?: null | string;\n /** Separator between page title and site name. Defaults to ' | '. */\n separator?: string;\n /** Site name, e.g. 'Acme Inc'. */\n siteName?: null | string;\n};\n/**\n * Composes a full document title from a page title and the site name.\n *\n * - both, page-first: \"About Us | Acme Inc\"\n * - both, site-first: \"Acme Inc | About Us\"\n * - page only: \"About Us\"\n * - site only: \"Acme Inc\"\n * - neither: \"\"\n *\n * Pure function — no dependency on Payload or request state.\n */\nexport declare function composeTitle({ order, pageTitle, separator, siteName, }: ComposeTitleArgs): string;\nexport {};\n"],"names":[],"mappings":"AAAA,gDAAgD,GAwBhD,WAAU"} \ No newline at end of file diff --git a/dist/modules/seo/createMetadataGenerator.d.js b/dist/modules/seo/createMetadataGenerator.d.js deleted file mode 100644 index 0ccaf81..0000000 --- a/dist/modules/seo/createMetadataGenerator.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=createMetadataGenerator.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/createMetadataGenerator.d.js.map b/dist/modules/seo/createMetadataGenerator.d.js.map deleted file mode 100644 index 3266fc7..0000000 --- a/dist/modules/seo/createMetadataGenerator.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["createMetadataGenerator.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { I18nConfig } from '../i18n/index.js';\nimport type { PageMetadata } from './buildMetadata.js';\nimport type { SeoMeta } from './types.js';\n/**\n * A document as needed for metadata: its SEO meta group and localized slug.\n */\ntype MetadataDocument = {\n meta?: null | SeoMeta;\n slug?: null | Record;\n};\ntype CreateMetadataGeneratorArgs = {\n /** Absolute site origin, e.g. 'https://example.com'. */\n baseUrl?: string;\n config: I18nConfig;\n /** Home slug that collapses to the locale root. Defaults to 'home'. */\n homeSlug?: string;\n /**\n * Resolves the document to build metadata for, given route params.\n * The client supplies this (they own the collections and routing); it should\n * fetch with `locale: 'all'` so the slug field is a locale→value map.\n */\n resolveDocument: (args: {\n locale: string;\n params: Record;\n payload: BasePayload;\n }) => Promise;\n /** Resolves the OG image URL for the document, if any. */\n resolveImageUrl?: (args: {\n doc: MetadataDocument;\n locale: string;\n payload: BasePayload;\n }) => Promise;\n /** Resolves the site name (e.g. from SiteSettings). */\n resolveSiteName?: (args: {\n locale: string;\n payload: BasePayload;\n }) => Promise;\n};\n/**\n * Builds a metadata generator, collapsing the usual generateMetadata\n * boilerplate into a single wired-up function.\n *\n * The client provides resolvers (they own collections/routing); the plugin\n * owns the assembly (title composition, canonical, hreflang, OG).\n *\n * The returned function takes `{ payload, params, locale }` — Next calls\n * `generateMetadata({ params })` without those, and the plugin never calls\n * getPayload itself, so the client wraps it in their route file:\n *\n * ```ts\n * // app/(frontend)/[locale]/[[...slug]]/page.tsx\n * const generate = createMetadataGenerator({\n * config: i18nConfig,\n * baseUrl: process.env.NEXT_PUBLIC_SERVER_URL,\n * resolveDocument: async ({ payload, params, locale }) => { ... },\n * })\n *\n * export async function generateMetadata({ params }) {\n * const { locale, slug } = await params\n * const payload = await getPayload({ config: await config })\n * return generate({ payload, params: { slug: slug ?? [] }, locale })\n * }\n * ```\n *\n * `resolveDocument` should fetch with `locale: 'all'` so the slug field comes\n * back as a locale→value map — that's what hreflang alternates are built from.\n */\nexport declare function createMetadataGenerator(args: CreateMetadataGeneratorArgs): (context: {\n locale: string;\n params: Record;\n payload: BasePayload;\n}) => Promise;\nexport {};\n"],"names":[],"mappings":"AAyEA,WAAU"} \ No newline at end of file diff --git a/dist/modules/seo/createPageMetadata.d.js b/dist/modules/seo/createPageMetadata.d.js deleted file mode 100644 index ca5b5e1..0000000 --- a/dist/modules/seo/createPageMetadata.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=createPageMetadata.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/createPageMetadata.d.js.map b/dist/modules/seo/createPageMetadata.d.js.map deleted file mode 100644 index c97008e..0000000 --- a/dist/modules/seo/createPageMetadata.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["createPageMetadata.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { ContentOption } from '../content/index.js';\nimport type { I18nConfig } from '../i18n/index.js';\nimport type { PageMetadata } from './buildMetadata.js';\ntype CreatePageMetadataArgs = {\n /** Absolute site origin, e.g. 'https://example.com'. */\n baseUrl?: string;\n /** Collection holding pages. Defaults to 'pages'. */\n collection?: string;\n config: I18nConfig;\n /**\n * Archive-backed collections, same value as the plugin option. Pass it and\n * entry URLs (/pl/artykuly/moj-post) get correct canonical and hreflang;\n * omit it and only pages are handled.\n */\n content?: ContentOption;\n /** SiteSettings global slug. Defaults to 'site-settings'. */\n settingsSlug?: string;\n /** Field on SiteSettings holding the site name. Defaults to 'siteName'. */\n siteNameField?: string;\n};\ntype PageMetadataContext = {\n locale: string;\n /**\n * Page number from ?page= on an archive listing. Pass it and page 2 gets a\n * canonical to itself; leave it out and every page claims to be page 1.\n */\n page?: number;\n payload: BasePayload;\n /** Route slug segments; empty/undefined means the locale root. */\n slug?: string[];\n};\n/**\n * Metadata for the page route, with every resolver already wired.\n *\n * `createMetadataGenerator` asks the client for resolvers because it can't know\n * their collections. But for the plugin's own conventions it does know: pages\n * live in one collection, the site name sits on SiteSettings, the OG image sits\n * on the plugin-seo `meta` group, the home page is whatever System Pages points\n * at, and — with `content` — entries live under their collection's archive page.\n * Re-declaring all that in every project is copy-paste, so this resolves it.\n *\n * Reach for `createMetadataGenerator` instead when a route doesn't follow those\n * conventions — custom image logic, a different global, hand-rolled paths.\n *\n * The plugin never calls getPayload, and Next calls generateMetadata without a\n * payload, so the client keeps a small wrapper:\n *\n * ```ts\n * const pageMetadata = createPageMetadata({ config: i18nConfig, baseUrl, content })\n *\n * export async function generateMetadata({ params }) {\n * const { locale, slug } = await params\n * return pageMetadata({ payload: await getPayload({ config }), locale, slug })\n * }\n * ```\n */\nexport declare function createPageMetadata(args: CreatePageMetadataArgs): ({ slug, locale, page, payload, }: PageMetadataContext) => Promise;\nexport {};\n"],"names":[],"mappings":"AA0DA,WAAU"} \ No newline at end of file diff --git a/dist/modules/seo/hreflang.d.js b/dist/modules/seo/hreflang.d.js deleted file mode 100644 index 187a70a..0000000 --- a/dist/modules/seo/hreflang.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=hreflang.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/hreflang.d.js.map b/dist/modules/seo/hreflang.d.js.map deleted file mode 100644 index 95e305b..0000000 --- a/dist/modules/seo/hreflang.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["hreflang.d.ts"],"sourcesContent":["import type { I18nConfig, LocalizedSlugs } from '../i18n/index.js';\ntype BuildHreflangArgs = {\n /** Absolute site origin, e.g. 'https://example.com'. Omit for relative paths. */\n baseUrl?: string;\n config: I18nConfig;\n /** Home slug that collapses to the locale root. Defaults to 'home'. */\n homeSlug?: string;\n /**\n * Localized segment the document lives under (an archive page's slugs),\n * e.g. { pl: 'artykuly', en: 'articles' }. Locales missing from the prefix\n * are omitted — an entry with no archive in that language has no URL there.\n */\n prefix?: LocalizedSlugs;\n /** slug per locale for the current document, e.g. { pl: 'o-nas', en: 'about' } */\n slugs: LocalizedSlugs;\n};\n/**\n * Builds a map of locale → URL for hreflang alternate links, suitable for\n * Next.js Metadata `alternates.languages`.\n *\n * Bridges SEO and i18n: for each configured locale that the document has a\n * slug in, it produces the locale-aware path (via buildLocalizedPath),\n * optionally prefixed with an absolute origin.\n *\n * @example\n * buildHreflangAlternates({\n * slugs: { pl: 'o-nas', en: 'about' },\n * config,\n * baseUrl: 'https://example.com',\n * })\n * // → { pl: 'https://example.com/pl/o-nas', en: 'https://example.com/en/about' }\n */\nexport declare function buildHreflangAlternates({ baseUrl, config, homeSlug, prefix, slugs, }: BuildHreflangArgs): Record;\nexport {};\n"],"names":[],"mappings":"AAiCA,WAAU"} \ No newline at end of file diff --git a/dist/modules/seo/index.d.js b/dist/modules/seo/index.d.js deleted file mode 100644 index aefea18..0000000 --- a/dist/modules/seo/index.d.js +++ /dev/null @@ -1,15 +0,0 @@ -export { buildAutoFillMetaHook } from './autoFillMeta.js'; -export { buildMetadata } from './buildMetadata.js'; -export { buildRobots } from './buildRobots.js'; -export { buildSitemapEntries } from './buildSitemapEntries.js'; -export { composeTitle } from './composeTitle.js'; -export { createMetadataGenerator } from './createMetadataGenerator.js'; -export { createPageMetadata } from './createPageMetadata.js'; -export { buildHreflangAlternates } from './hreflang.js'; -export { injectAutoFillMeta } from './injectAutoFillMeta.js'; -export { injectSeoTabs } from './injectSeoTabs.js'; -export { readSiteMetaConfig } from './readSiteMetaConfig.js'; -export { buildSeoPlugin } from './seoPluginConfig.js'; -export { slugsAcrossLocales } from './slugsAcrossLocales.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/index.d.js.map b/dist/modules/seo/index.d.js.map deleted file mode 100644 index ce33326..0000000 --- a/dist/modules/seo/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { buildAutoFillMetaHook } from './autoFillMeta.js';\nexport type { AutoFillMapping } from './autoFillMeta.js';\nexport { buildMetadata } from './buildMetadata.js';\nexport type { PageMetadata } from './buildMetadata.js';\nexport { buildRobots } from './buildRobots.js';\nexport type { RobotsRules } from './buildRobots.js';\nexport { buildSitemapEntries } from './buildSitemapEntries.js';\nexport type { SitemapEntry } from './buildSitemapEntries.js';\nexport { composeTitle } from './composeTitle.js';\nexport type { TitleOrder } from './composeTitle.js';\nexport { createMetadataGenerator } from './createMetadataGenerator.js';\nexport { createPageMetadata } from './createPageMetadata.js';\nexport { buildHreflangAlternates } from './hreflang.js';\nexport { injectAutoFillMeta } from './injectAutoFillMeta.js';\nexport { injectSeoTabs } from './injectSeoTabs.js';\nexport { readSiteMetaConfig } from './readSiteMetaConfig.js';\nexport type { SiteMetaConfig } from './readSiteMetaConfig.js';\nexport { buildSeoPlugin } from './seoPluginConfig.js';\nexport { slugsAcrossLocales } from './slugsAcrossLocales.js';\nexport type { SeoMeta, SeoOption } from './types.js';\n"],"names":["buildAutoFillMetaHook","buildMetadata","buildRobots","buildSitemapEntries","composeTitle","createMetadataGenerator","createPageMetadata","buildHreflangAlternates","injectAutoFillMeta","injectSeoTabs","readSiteMetaConfig","buildSeoPlugin","slugsAcrossLocales"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,oBAAoB;AAE1D,SAASC,aAAa,QAAQ,qBAAqB;AAEnD,SAASC,WAAW,QAAQ,mBAAmB;AAE/C,SAASC,mBAAmB,QAAQ,2BAA2B;AAE/D,SAASC,YAAY,QAAQ,oBAAoB;AAEjD,SAASC,uBAAuB,QAAQ,+BAA+B;AACvE,SAASC,kBAAkB,QAAQ,0BAA0B;AAC7D,SAASC,uBAAuB,QAAQ,gBAAgB;AACxD,SAASC,kBAAkB,QAAQ,0BAA0B;AAC7D,SAASC,aAAa,QAAQ,qBAAqB;AACnD,SAASC,kBAAkB,QAAQ,0BAA0B;AAE7D,SAASC,cAAc,QAAQ,uBAAuB;AACtD,SAASC,kBAAkB,QAAQ,0BAA0B"} \ No newline at end of file diff --git a/dist/modules/seo/injectAutoFillMeta.d.js b/dist/modules/seo/injectAutoFillMeta.d.js deleted file mode 100644 index 221c8f4..0000000 --- a/dist/modules/seo/injectAutoFillMeta.d.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Injects the auto-fill meta hook into every SEO-enabled collection. - * - * Runs after @payloadcms/plugin-seo has added the meta group, appending a - * beforeChange hook that fills empty meta from document content. Existing - * hooks are preserved (plugin hook runs last, so editor input and other hooks - * win first). - */ export { }; - -//# sourceMappingURL=injectAutoFillMeta.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/injectAutoFillMeta.d.js.map b/dist/modules/seo/injectAutoFillMeta.d.js.map deleted file mode 100644 index 68545b3..0000000 --- a/dist/modules/seo/injectAutoFillMeta.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["injectAutoFillMeta.d.ts"],"sourcesContent":["import type { Config } from 'payload';\nimport type { SeoOption } from './types.js';\n/**\n * Injects the auto-fill meta hook into every SEO-enabled collection.\n *\n * Runs after @payloadcms/plugin-seo has added the meta group, appending a\n * beforeChange hook that fills empty meta from document content. Existing\n * hooks are preserved (plugin hook runs last, so editor input and other hooks\n * win first).\n */\nexport declare function injectAutoFillMeta(config: Config, seo: SeoOption): Config;\n"],"names":[],"mappings":"AAEA;;;;;;;CAOC,GACD,WAAmF"} \ No newline at end of file diff --git a/dist/modules/seo/injectSeoTabs.d.js b/dist/modules/seo/injectSeoTabs.d.js deleted file mode 100644 index 2053e8e..0000000 --- a/dist/modules/seo/injectSeoTabs.d.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Wraps each SEO-enabled collection's fields into a tabbed UI: a "Content" tab - * holding the collection's own fields, and an "SEO" tab holding the `meta` - * group that @payloadcms/plugin-seo added. - * - * This replaces plugin-seo's own `tabbedUI`, which merges tabs by inspecting - * the first field and breaks when other plugins/fields (roles, slug) already - * sit in the collection — producing an empty SEO tab. Running this AFTER - * plugin-seo (so `meta` already exists) and after other field injections lets - * us build the tabs deterministically. - * - * If a collection's first field is already a tabs field, the SEO tab is - * appended to it instead of creating a new wrapper. - */ export { }; - -//# sourceMappingURL=injectSeoTabs.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/injectSeoTabs.d.js.map b/dist/modules/seo/injectSeoTabs.d.js.map deleted file mode 100644 index b53750b..0000000 --- a/dist/modules/seo/injectSeoTabs.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["injectSeoTabs.d.ts"],"sourcesContent":["import type { Config } from 'payload';\nimport type { SeoOption } from './types.js';\n/**\n * Wraps each SEO-enabled collection's fields into a tabbed UI: a \"Content\" tab\n * holding the collection's own fields, and an \"SEO\" tab holding the `meta`\n * group that @payloadcms/plugin-seo added.\n *\n * This replaces plugin-seo's own `tabbedUI`, which merges tabs by inspecting\n * the first field and breaks when other plugins/fields (roles, slug) already\n * sit in the collection — producing an empty SEO tab. Running this AFTER\n * plugin-seo (so `meta` already exists) and after other field injections lets\n * us build the tabs deterministically.\n *\n * If a collection's first field is already a tabs field, the SEO tab is\n * appended to it instead of creating a new wrapper.\n */\nexport declare function injectSeoTabs(config: Config, seo: SeoOption): Config;\n"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;CAaC,GACD,WAA8E"} \ No newline at end of file diff --git a/dist/modules/seo/readSiteMetaConfig.d.js b/dist/modules/seo/readSiteMetaConfig.d.js deleted file mode 100644 index 3503ba4..0000000 --- a/dist/modules/seo/readSiteMetaConfig.d.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Reads the site-wide inputs to title and URL composition from SiteSettings. - * - * Split out of metadata assembly because these are one concern with one source: - * whatever an editor set in the panel. Metadata generation shouldn't also know - * that the separator arrives unpadded, or that the home slug hides inside a - * relationship — it should receive a resolved config. - */ export { }; - -//# sourceMappingURL=readSiteMetaConfig.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/readSiteMetaConfig.d.js.map b/dist/modules/seo/readSiteMetaConfig.d.js.map deleted file mode 100644 index 2f17e5d..0000000 --- a/dist/modules/seo/readSiteMetaConfig.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["readSiteMetaConfig.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { TitleOrder } from './composeTitle.js';\nexport type SiteMetaConfig = {\n /** Slug of the page assigned as Homepage; collapses to the locale root. */\n homeSlug?: string;\n order?: TitleOrder;\n /** Padded separator, e.g. ' | ' — the panel stores the bare character. */\n separator?: string;\n siteName: null | string;\n};\n/**\n * Reads the site-wide inputs to title and URL composition from SiteSettings.\n *\n * Split out of metadata assembly because these are one concern with one source:\n * whatever an editor set in the panel. Metadata generation shouldn't also know\n * that the separator arrives unpadded, or that the home slug hides inside a\n * relationship — it should receive a resolved config.\n */\nexport declare function readSiteMetaConfig({ locale, payload, settingsSlug, siteNameField, }: {\n locale: string;\n payload: BasePayload;\n settingsSlug?: string;\n siteNameField?: string;\n}): Promise;\n"],"names":[],"mappings":"AAUA;;;;;;;CAOC,GACD,WAK4B"} \ No newline at end of file diff --git a/dist/modules/seo/seoPluginConfig.d.js b/dist/modules/seo/seoPluginConfig.d.js deleted file mode 100644 index a2e4af3..0000000 --- a/dist/modules/seo/seoPluginConfig.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=seoPluginConfig.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/seoPluginConfig.d.js.map b/dist/modules/seo/seoPluginConfig.d.js.map deleted file mode 100644 index e8ee499..0000000 --- a/dist/modules/seo/seoPluginConfig.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["seoPluginConfig.d.ts"],"sourcesContent":["import type { Plugin } from 'payload';\nimport type { SeoOption } from './types.js';\ntype BuildSeoPluginArgs = {\n seo: SeoOption;\n /** Upload collection slug for the meta image (typically 'media'). */\n uploadsCollection?: string;\n};\n/**\n * Configures @payloadcms/plugin-seo from IPAL's SeoOption.\n *\n * Adds the `meta` field group (title, description, image) to the client's\n * chosen collections. tabbedUI is intentionally NOT used — it merges tabs by\n * inspecting the first field, which breaks when other plugins/fields (roles,\n * slug) already sit in the collection, leaving an empty SEO tab. Instead the\n * SEO UI fields are injected into a controlled tab by injectSeoTabs.\n */\nexport declare function buildSeoPlugin({ seo, uploadsCollection }: BuildSeoPluginArgs): Plugin;\nexport {};\n"],"names":[],"mappings":"AAiBA,WAAU"} \ No newline at end of file diff --git a/dist/modules/seo/slugsAcrossLocales.d.js b/dist/modules/seo/slugsAcrossLocales.d.js deleted file mode 100644 index 6547b06..0000000 --- a/dist/modules/seo/slugsAcrossLocales.d.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Reads a document's slug in every locale — the map hreflang alternates are - * built from. - * - * Needs its own query because a document fetched in one locale returns `slug` - * as a plain string. Fetching with `locale: 'all'` turns *every* localized - * field into a locale→value map, which is right for the slug and wrong for - * everything else (a title map would break title composition), so this asks - * only for what it needs and at depth 0. - */ export { }; - -//# sourceMappingURL=slugsAcrossLocales.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/slugsAcrossLocales.d.js.map b/dist/modules/seo/slugsAcrossLocales.d.js.map deleted file mode 100644 index 4ce6bda..0000000 --- a/dist/modules/seo/slugsAcrossLocales.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["slugsAcrossLocales.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\nimport type { I18nConfig, LocalizedSlugs } from '../i18n/index.js';\n/**\n * Reads a document's slug in every locale — the map hreflang alternates are\n * built from.\n *\n * Needs its own query because a document fetched in one locale returns `slug`\n * as a plain string. Fetching with `locale: 'all'` turns *every* localized\n * field into a locale→value map, which is right for the slug and wrong for\n * everything else (a title map would break title composition), so this asks\n * only for what it needs and at depth 0.\n */\nexport declare function slugsAcrossLocales({ id, collection, config, payload, }: {\n collection: string;\n config: I18nConfig;\n id: number | string;\n payload: BasePayload;\n}): Promise;\n"],"names":[],"mappings":"AAEA;;;;;;;;;CASC,GACD,WAK4B"} \ No newline at end of file diff --git a/dist/modules/seo/types.d.js b/dist/modules/seo/types.d.js deleted file mode 100644 index faa1288..0000000 --- a/dist/modules/seo/types.d.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Minimal shape of the SEO meta group as stored on a document by - * @payloadcms/plugin-seo. The client's generated types are richer; helpers - * depend only on this. - */ export { }; - -//# sourceMappingURL=types.d.js.map \ No newline at end of file diff --git a/dist/modules/seo/types.d.js.map b/dist/modules/seo/types.d.js.map deleted file mode 100644 index 996fb77..0000000 --- a/dist/modules/seo/types.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["types.d.ts"],"sourcesContent":["import type { Field } from 'payload';\nimport type { AutoFillMapping } from './autoFillMeta.js';\n/**\n * SEO configuration.\n *\n * The plugin wires @payloadcms/plugin-seo into the client's config and adds\n * locale-aware metadata helpers on top. Collections come from options because\n * the plugin doesn't own the client's content collections (e.g. Pages).\n */\nexport type SeoOption = {\n /**\n * Auto-fill empty meta from document fields on save. Defaults to the website\n * template mapping (title → meta.title). Set to false to disable.\n */\n autoFill?: AutoFillMapping | false;\n /** Collection slugs that receive SEO meta fields, e.g. ['pages', 'posts']. */\n collections: string[];\n /** Extra fields appended to the SEO group in the admin. */\n fields?: Field[];\n /** Optional: customize how meta descriptions are generated. */\n generateDescription?: (args: {\n doc: Record;\n }) => string;\n /** Optional: customize how meta titles are generated in the admin preview. */\n generateTitle?: (args: {\n doc: Record;\n }) => string;\n};\n/**\n * Minimal shape of the SEO meta group as stored on a document by\n * @payloadcms/plugin-seo. The client's generated types are richer; helpers\n * depend only on this.\n */\nexport type SeoMeta = {\n description?: null | string;\n image?: unknown;\n title?: null | string;\n /** When set, used as the whole title — no site name, no separator. */\n titleOverride?: null | string;\n};\n"],"names":[],"mappings":"AA4BA;;;;CAIC,GACD,WAME"} \ No newline at end of file diff --git a/dist/modules/slug/buildSlugField.d.js b/dist/modules/slug/buildSlugField.d.js deleted file mode 100644 index 7d8609f..0000000 --- a/dist/modules/slug/buildSlugField.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { }; - -//# sourceMappingURL=buildSlugField.d.js.map \ No newline at end of file diff --git a/dist/modules/slug/buildSlugField.d.js.map b/dist/modules/slug/buildSlugField.d.js.map deleted file mode 100644 index bd237af..0000000 --- a/dist/modules/slug/buildSlugField.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["buildSlugField.d.ts"],"sourcesContent":["import type { Field, TextField } from 'payload';\n/**\n * Normalizes a string into a URL slug. slugify handles diacritics out of the\n * box (Polish included: \"Strona główna\" → \"strona-glowna\").\n */\nexport declare function toSlug(input: string): string;\ntype BuildSlugFieldOptions = {\n /** Source field to derive the slug from. Default: 'title'. */\n from?: string;\n /** Whether the slug is localized (per-locale). Default: true. */\n localized?: boolean;\n /** Field name for the slug. Default: 'slug'. */\n name?: string;\n /** Override or extend the generated field config. */\n overrides?: Partial;\n /** Whether the slug is required. Default: true. */\n required?: boolean;\n};\n/**\n * Builds a slug field that auto-generates from a source field (default 'title')\n * only when left empty — an editor's manual slug is never overwritten (mode 4a).\n *\n * Localized-safe: on a localized field Payload runs the hook per locale, so\n * `value` is the slug for the active locale and `siblingData[from]` is the\n * source in that same locale. Editing the doc in 'pl' fills slug.pl from\n * title.pl; editing in 'en' fills slug.en from title.en — giving genuinely\n * per-locale slugs (strona-glowna / homepage) that the language switcher needs.\n */\nexport declare function buildSlugField(options?: BuildSlugFieldOptions): Field;\nexport {};\n"],"names":[],"mappings":"AA6BA,WAAU"} \ No newline at end of file diff --git a/dist/modules/slug/index.d.js b/dist/modules/slug/index.d.js deleted file mode 100644 index 64e64b4..0000000 --- a/dist/modules/slug/index.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { buildSlugField, toSlug } from './buildSlugField.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/slug/index.d.js.map b/dist/modules/slug/index.d.js.map deleted file mode 100644 index 911da2d..0000000 --- a/dist/modules/slug/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { buildSlugField, toSlug } from './buildSlugField.js';\n"],"names":["buildSlugField","toSlug"],"mappings":"AAAA,SAASA,cAAc,EAAEC,MAAM,QAAQ,sBAAsB"} \ No newline at end of file diff --git a/dist/modules/turnstile/Turnstile.d.js b/dist/modules/turnstile/Turnstile.d.js deleted file mode 100644 index 1cc0c89..0000000 --- a/dist/modules/turnstile/Turnstile.d.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Cloudflare Turnstile widget — reusable across any form. Renders the challenge - * and reports the token via onToken. The token must then be verified - * server-side (see verifyTurnstile) before a submission is trusted. - * - * siteKey is a prop rather than an env var so all Turnstile config lives in one - * place (SiteIntegrations), consistent with the plugin's panel-managed model. - * The script is injected directly (no next/script dependency) so the widget - * stays framework-agnostic. - */ export { }; - -//# sourceMappingURL=Turnstile.d.js.map \ No newline at end of file diff --git a/dist/modules/turnstile/Turnstile.d.js.map b/dist/modules/turnstile/Turnstile.d.js.map deleted file mode 100644 index 13d4934..0000000 --- a/dist/modules/turnstile/Turnstile.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["Turnstile.d.ts"],"sourcesContent":["declare global {\n interface Window {\n turnstile?: {\n render: (el: HTMLElement, opts: Record) => string;\n reset: (id?: string) => void;\n };\n }\n}\nexport type TurnstileProps = {\n /** Called with the token once solved, or null on expiry/error. */\n onToken: (token: null | string) => void;\n /**\n * Public Turnstile site key. The client project reads it server-side from\n * SiteIntegrations (turnstileSiteKey) and passes it in — the widget is a pure\n * client component and can't read Payload itself.\n */\n siteKey: string;\n theme?: 'auto' | 'dark' | 'light';\n};\n/**\n * Cloudflare Turnstile widget — reusable across any form. Renders the challenge\n * and reports the token via onToken. The token must then be verified\n * server-side (see verifyTurnstile) before a submission is trusted.\n *\n * siteKey is a prop rather than an env var so all Turnstile config lives in one\n * place (SiteIntegrations), consistent with the plugin's panel-managed model.\n * The script is injected directly (no next/script dependency) so the widget\n * stays framework-agnostic.\n */\nexport declare function Turnstile({ onToken, siteKey, theme }: TurnstileProps): import(\"react/jsx-runtime\").JSX.Element | null;\n"],"names":[],"mappings":"AAmBA;;;;;;;;;CASC,GACD,WAA+H"} \ No newline at end of file diff --git a/dist/modules/turnstile/client.d.js b/dist/modules/turnstile/client.d.js deleted file mode 100644 index 0a1f8b5..0000000 --- a/dist/modules/turnstile/client.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { Turnstile } from './Turnstile.js'; - -//# sourceMappingURL=client.d.js.map \ No newline at end of file diff --git a/dist/modules/turnstile/client.d.js.map b/dist/modules/turnstile/client.d.js.map deleted file mode 100644 index 5ade349..0000000 --- a/dist/modules/turnstile/client.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["client.d.ts"],"sourcesContent":["export { Turnstile } from './Turnstile.js';\nexport type { TurnstileProps } from './Turnstile.js';\n"],"names":["Turnstile"],"mappings":"AAAA,SAASA,SAAS,QAAQ,iBAAiB"} \ No newline at end of file diff --git a/dist/modules/turnstile/index.d.js b/dist/modules/turnstile/index.d.js deleted file mode 100644 index 1e062a4..0000000 --- a/dist/modules/turnstile/index.d.js +++ /dev/null @@ -1,3 +0,0 @@ -export { verifyTurnstile } from './verify.js'; - -//# sourceMappingURL=index.d.js.map \ No newline at end of file diff --git a/dist/modules/turnstile/index.d.js.map b/dist/modules/turnstile/index.d.js.map deleted file mode 100644 index 6067c5c..0000000 --- a/dist/modules/turnstile/index.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { verifyTurnstile } from './verify.js';\n"],"names":["verifyTurnstile"],"mappings":"AAAA,SAASA,eAAe,QAAQ,cAAc"} \ No newline at end of file diff --git a/dist/modules/turnstile/verify.d.js b/dist/modules/turnstile/verify.d.js deleted file mode 100644 index 1292653..0000000 --- a/dist/modules/turnstile/verify.d.js +++ /dev/null @@ -1,3 +0,0 @@ -import 'server-only'; - -//# sourceMappingURL=verify.d.js.map \ No newline at end of file diff --git a/dist/modules/turnstile/verify.d.js.map b/dist/modules/turnstile/verify.d.js.map deleted file mode 100644 index e9a8b17..0000000 --- a/dist/modules/turnstile/verify.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["verify.d.ts"],"sourcesContent":["import 'server-only';\nimport type { BasePayload } from 'payload';\ntype VerifyTurnstileArgs = {\n /** Optional client IP for stricter verification. */\n ip?: string;\n /** Payload instance — used to read the secret from SiteIntegrations. */\n payload: BasePayload;\n /** Token produced by the client-side widget. */\n token: string;\n};\n/**\n * Verifies a Turnstile token with Cloudflare, server-side only.\n *\n * The secret comes from the SiteIntegrations global (editor-managed, per the\n * plugin's \"secrets in the panel\" model), read via the Local API which bypasses\n * access control. `server-only` guarantees this never reaches the browser\n * bundle, keeping the secret off the client.\n *\n * Returns false on any failure (missing secret/token, network error, rejected\n * challenge) — callers treat false as \"do not trust this submission\".\n */\nexport declare function verifyTurnstile({ ip, payload, token, }: VerifyTurnstileArgs): Promise;\nexport {};\n"],"names":[],"mappings":"AAAA,OAAO,cAAc"} \ No newline at end of file diff --git a/dist/plugin.d.js b/dist/plugin.d.js deleted file mode 100644 index aa0c91c..0000000 --- a/dist/plugin.d.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * IPAL (Intecion Payload Advanced Library) plugin for Payload CMS 3. - * - * @example - * ```ts - * import { ipalKit } from 'ipal-kit' - * - * export default buildConfig({ - * plugins: [ - * ipalKit({ - * i18n: { - * locales: [ - * { code: 'pl', label: 'Polski' }, - * { code: 'en', label: 'English' }, - * ], - * defaultLocale: 'pl', - * }, - * access: { authCollection: 'users' }, - * }), - * ], - * }) - * ``` - */ export { }; - -//# sourceMappingURL=plugin.d.js.map \ No newline at end of file diff --git a/dist/plugin.d.js.map b/dist/plugin.d.js.map deleted file mode 100644 index 99164a6..0000000 --- a/dist/plugin.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["plugin.d.ts"],"sourcesContent":["import type { Plugin } from 'payload';\nimport type { IpalOptions } from './types.js';\n/**\n * IPAL (Intecion Payload Advanced Library) plugin for Payload CMS 3.\n *\n * @example\n * ```ts\n * import { ipalKit } from 'ipal-kit'\n *\n * export default buildConfig({\n * plugins: [\n * ipalKit({\n * i18n: {\n * locales: [\n * { code: 'pl', label: 'Polski' },\n * { code: 'en', label: 'English' },\n * ],\n * defaultLocale: 'pl',\n * },\n * access: { authCollection: 'users' },\n * }),\n * ],\n * })\n * ```\n */\nexport declare const ipalKit: (options: IpalOptions) => Plugin;\n"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;CAsBC,GACD,WAA+D"} \ No newline at end of file diff --git a/dist/types.d.js b/dist/types.d.js deleted file mode 100644 index 4d1830e..0000000 --- a/dist/types.d.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Configuration options for the IPAL plugin. - * Passed by the client project in payload.config.ts. - */ export { }; - -//# sourceMappingURL=types.d.js.map \ No newline at end of file diff --git a/dist/types.d.js.map b/dist/types.d.js.map deleted file mode 100644 index 42184a7..0000000 --- a/dist/types.d.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["types.d.ts"],"sourcesContent":["import type { Field } from 'payload';\nimport type { AccessOption } from './modules/access/types.js';\nimport type { ContentOption } from './modules/content/types.js';\nimport type { FormsOption } from './modules/forms/types.js';\nimport type { I18nConfig } from './modules/i18n/types.js';\nimport type { PagesOption } from './modules/pages/types.js';\nimport type { SeoOption } from './modules/seo/types.js';\n/**\n * Configuration options for the IPAL plugin.\n * Passed by the client project in payload.config.ts.\n */\nexport type IpalOptions = {\n /**\n * Role-based access control. Injects a fixed `roles` field\n * (admin > editor > user) into the client's auth collection.\n */\n access?: AccessOption;\n /**\n * Collections whose entries live under an archive page — blog posts, case\n * studies, anything with a listing. Adds an \"archive page\" assignment per\n * collection in SiteSettings; the assigned page's localized slug becomes the\n * URL segment (/pl/artykuly/moj-post, /en/articles/my-post). Requires `pages`.\n */\n content?: ContentOption;\n /** Disable the plugin without uninstalling (keeps DB schema intact) */\n enabled?: boolean;\n /**\n * Forms — form-builder collections (forms, form-submissions) plus the\n * callable submitForm (Turnstile + persistence + SMTP-from-panel email).\n */\n forms?: FormsOption;\n /** Internationalization — locales, default locale, fallback behavior */\n i18n: I18nConfig;\n /** Additional fields injected into SiteIntegrations global */\n integrationsFields?: Field[];\n /**\n * System-page assignments (homepage, privacy, cookies) in SiteSettings.\n * Provide the slug of the client's Pages collection to enable.\n */\n pages?: PagesOption;\n /**\n * SEO — adds meta fields to chosen collections (via @payloadcms/plugin-seo)\n * and enables locale-aware metadata helpers.\n */\n seo?: SeoOption;\n /** Additional fields injected into SiteSettings global */\n siteSettingsFields?: Field[];\n};\n"],"names":[],"mappings":"AAOA;;;CAGC,GACD,WAoCE"} \ No newline at end of file diff --git a/src/modules/consent/useConsent.ts b/src/modules/consent/useConsent.ts index e71fe3a..65f25e0 100644 --- a/src/modules/consent/useConsent.ts +++ b/src/modules/consent/useConsent.ts @@ -3,11 +3,28 @@ import { useCallback, useEffect, useState } from 'react' import type { ConsentCategory, ConsentState } from './categories.js' +import { LOCALE_COOKIE_NAME } from '../i18n/index.js' import { ACCEPT_ALL_CONSENT, DEFAULT_CONSENT, REJECT_ALL_CONSENT } from './categories.js' import { updateConsent } from './googleConsent.js' import { CONSENT_COOKIE, CONSENT_MAX_AGE, parseConsent, serializeConsent } from './storage.js' -export function useConsent() { +/** + * Cookies to delete when consent for a category is withdrawn. Keyed by + * category. The plugin knows about its own functional cookie (locale); clients + * can extend this via the `cookieMap` arg to useConsent if they set their own. + */ +const DEFAULT_COOKIE_MAP: Partial> = { + functional: [LOCALE_COOKIE_NAME], +} + +/** Expire a cookie now, across the whole site. */ +function deleteCookie(name: string) { + document.cookie = `${name}=;path=/;max-age=0;samesite=lax` +} + +export function useConsent( + cookieMap: Partial> = DEFAULT_COOKIE_MAP, +) { const [state, setState] = useState(DEFAULT_CONSENT) const [decided, setDecided] = useState(false) @@ -23,16 +40,31 @@ export function useConsent() { } }, []) - const persist = useCallback((next: ConsentState) => { - document.cookie = `${CONSENT_COOKIE}=${serializeConsent(next)};path=/;max-age=${CONSENT_MAX_AGE};samesite=lax` - setState(next) - setDecided(true) - // Tell Google right away. Tags are already on the page holding whatever - // defaults Analytics set at load; without this update they keep them for - // the rest of the session and never write their cookies — the banner would - // look like it worked while nothing changed. - updateConsent(next) - }, []) + const persist = useCallback( + (next: ConsentState) => { + // Withdrawal cleanup: for any category flipping true → false, delete the + // cookies tied to it. GDPR: withdrawing consent must stop the processing, + // so a functional cookie (e.g. locale) written under consent has to go when + // that consent is revoked. Uses the current `state` as the previous value. + for (const cat of Object.keys(cookieMap) as ConsentCategory[]) { + const wasGranted = state[cat] === true + const nowDenied = next[cat] !== true + if (wasGranted && nowDenied) { + for (const name of cookieMap[cat] ?? []) {deleteCookie(name)} + } + } + + document.cookie = `${CONSENT_COOKIE}=${serializeConsent(next)};path=/;max-age=${CONSENT_MAX_AGE};samesite=lax` + setState(next) + setDecided(true) + // Tell Google right away. Tags are already on the page holding whatever + // defaults Analytics set at load; without this update they keep them for + // the rest of the session and never write their cookies — the banner would + // look like it worked while nothing changed. + updateConsent(next) + }, + [state, cookieMap], + ) const acceptAll = useCallback(() => persist(ACCEPT_ALL_CONSENT), [persist]) const rejectAll = useCallback(() => persist(REJECT_ALL_CONSENT), [persist]) diff --git a/src/modules/i18n/localeMiddleware.ts b/src/modules/i18n/localeMiddleware.ts index e32ca35..01b77b2 100644 --- a/src/modules/i18n/localeMiddleware.ts +++ b/src/modules/i18n/localeMiddleware.ts @@ -1,5 +1,6 @@ import type { I18nConfig } from './types.js' +import { CONSENT_COOKIE, parseConsent } from '../consent/storage.js' import { isValidLocale, LOCALE_COOKIE_NAME, negotiateLocale } from '../i18n/index.js' /** @@ -14,15 +15,26 @@ type MiddlewareRequest = { } /** - * What the factory returns — the caller (in Next next-middleware.ts) decides how to + * What the factory returns — the caller (in Next middleware.ts) decides how to * act: `redirect` means send a 307 to `location` and set the locale cookie; * `next` means let the request pass through untouched. */ export type LocaleMiddlewareResult = - { cookie: { name: string; value: string }; location: string; type: 'redirect' } | { type: 'next' } + | { cookie?: { name: string; value: string }; location: string; type: 'redirect' } + | { type: 'next' } type CreateLocaleMiddlewareArgs = { config: I18nConfig + /** + * Consent category that gates *persisting* the locale cookie. The locale is + * always detected (routing works regardless), but the choice is only written + * to a cookie once the visitor has consented to this category. Defaults to + * 'functional'. Pass 'necessary' to always persist (treat locale as strictly + * necessary), which restores the pre-consent behaviour. + */ + consentCategory?: 'functional' | 'necessary' + /** Name of the consent cookie to read. Defaults to CONSENT_COOKIE. */ + consentCookieName?: string /** Cookie name for the locale choice. Defaults to LOCALE_COOKIE_NAME. */ cookieName?: string } @@ -44,24 +56,28 @@ function firstSegment(pathname: string): string { * comes from negotiateLocale (cookie → Accept-Language → default) * - the chosen locale is written to a cookie so the next visit is stable * - * The plugin returns a decision; the thin next-middleware.ts in the client project + * The plugin returns a decision; the thin middleware.ts in the client project * turns it into a NextResponse. This keeps all logic in the plugin while - * respecting that next-middleware.ts must physically live in the client app. + * respecting that middleware.ts must physically live in the client app. * * @example - * // next-middleware.ts (client project) — one wiring file, no logic: + * // middleware.ts (client project) — one wiring file, no logic: * import { NextResponse } from 'next/server' * import { localeMiddleware } from './ipal.middleware' // created from this factory - * export function middleware(req) { + * export function proxy(req) { * const r = localeMiddleware(req) * if (r.type === 'next') return NextResponse.next() * const res = NextResponse.redirect(r.location) - * res.cookies.set(r.cookie.name, r.cookie.value) + * // cookie is optional: only present when the visitor consented to the + * // gating category (functional by default). Guard before setting. + * if (r.cookie) res.cookies.set(r.cookie.name, r.cookie.value) * return res * } */ export function createLocaleMiddleware({ config, + consentCategory = 'functional', + consentCookieName = CONSENT_COOKIE, cookieName = LOCALE_COOKIE_NAME, }: CreateLocaleMiddlewareArgs) { return function localeMiddleware(request: MiddlewareRequest): LocaleMiddlewareResult { @@ -83,10 +99,23 @@ export function createLocaleMiddleware({ const url = request.nextUrl.clone() url.pathname = `/${locale}${pathname === '/' ? '' : pathname}` + // Persist the locale choice ONLY if the visitor consented to the gating + // category. 'necessary' is always granted, so passing consentCategory: + // 'necessary' always persists. For 'functional' (default), we read the + // consent cookie and only write the locale cookie when functional is true. + // Without consent the locale is still detected each request (routing works), + // it just isn't remembered across visits — which is the whole point of + // gating a functional cookie behind consent. + let mayPersist = consentCategory === 'necessary' + if (!mayPersist) { + const consent = parseConsent(request.cookies.get(consentCookieName)?.value) + mayPersist = consent?.[consentCategory] === true + } + return { type: 'redirect', - cookie: { name: cookieName, value: locale }, location: url.toString(), + ...(mayPersist ? { cookie: { name: cookieName, value: locale } } : {}), } } }