This commit is contained in:
2026-07-31 23:21:51 +02:00
parent f6b4b36df8
commit f14f2cfd98
294 changed files with 5880 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
import type { I18nConfig } from '../i18n/index.js';
/**
* The shape we need from an assigned system-page document: its localized slug
* field, as returned by Payload when the parent is read with `locale: 'all'`.
*
* The plugin doesn't know the client's Pages type, so it depends only on this
* minimal contract.
*/
type AssignedPage = {
slug?: null | Record<string, unknown>;
};
type GetSystemPagePathArgs = {
config: I18nConfig;
/**
* Slug that represents the site root. Defaults to 'home'. When the assigned
* page's slug in the target locale equals this, the path collapses to the
* locale root (/pl, /en).
*/
homeSlug?: string;
/** Target locale to build the path for. */
locale: string;
/**
* The resolved system-page assignment from SiteSettings — the related
* document object (not just an ID), read with `locale: 'all'` so its slug
* is a locale→value map. Pass null/undefined if the role is unassigned.
*/
page: AssignedPage | null | undefined;
};
/**
* Resolves a system-page assignment to a locale-aware path.
*
* Bridges the Pages module (which document plays a role) and the i18n module
* (how that document's localized slug becomes a URL). This is what powers
* "visit /pl → serve the homepage": read SiteSettings.homepage, pass the
* related document here, get /pl/strona-glowna (or /pl if it's the home slug).
*
* Returns undefined when the role is unassigned or the assigned page has no
* slug in the target locale — the caller decides the fallback (e.g. 404,
* redirect to default locale).
*
* @example
* const settings = await payload.findGlobal({ slug: 'site-settings', locale: 'all', depth: 1 })
* getSystemPagePath({ page: settings.homepage, locale: 'pl', config })
* // → '/pl' (home slug collapses to root)
* getSystemPagePath({ page: settings.privacyPolicy, locale: 'en', config })
* // → '/en/privacy-policy'
*/
export declare function getSystemPagePath({ config, homeSlug, locale, page, }: GetSystemPagePathArgs): string | undefined;
export {};
+36
View File
@@ -0,0 +1,36 @@
import { buildLocalizedPath, getLocalizedSlugs } from '../i18n/index.js';
/**
* Resolves a system-page assignment to a locale-aware path.
*
* Bridges the Pages module (which document plays a role) and the i18n module
* (how that document's localized slug becomes a URL). This is what powers
* "visit /pl → serve the homepage": read SiteSettings.homepage, pass the
* related document here, get /pl/strona-glowna (or /pl if it's the home slug).
*
* Returns undefined when the role is unassigned or the assigned page has no
* slug in the target locale — the caller decides the fallback (e.g. 404,
* redirect to default locale).
*
* @example
* const settings = await payload.findGlobal({ slug: 'site-settings', locale: 'all', depth: 1 })
* getSystemPagePath({ page: settings.homepage, locale: 'pl', config })
* // → '/pl' (home slug collapses to root)
* getSystemPagePath({ page: settings.privacyPolicy, locale: 'en', config })
* // → '/en/privacy-policy'
*/ export function getSystemPagePath({ config, homeSlug = 'home', locale, page }) {
if (!page?.slug) {
return undefined;
}
const slugs = getLocalizedSlugs({
config,
slugField: page.slug
});
return buildLocalizedPath({
config,
homeSlug,
locale,
slugs
});
}
//# sourceMappingURL=getSystemPagePath.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/modules/pages/getSystemPagePath.ts"],"sourcesContent":["import type { I18nConfig } from '../i18n/index.js'\nimport type { SystemPageRole } from './types.js'\n\nimport { buildLocalizedPath, getLocalizedSlugs } from '../i18n/index.js'\n\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<string, unknown>\n}\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/**\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 function getSystemPagePath({\n config,\n homeSlug = 'home',\n locale,\n page,\n}: GetSystemPagePathArgs): string | undefined {\n if (!page?.slug) {\n return undefined\n }\n\n const slugs = getLocalizedSlugs({ config, slugField: page.slug })\n return buildLocalizedPath({ config, homeSlug, locale, slugs })\n}\n"],"names":["buildLocalizedPath","getLocalizedSlugs","getSystemPagePath","config","homeSlug","locale","page","slug","undefined","slugs","slugField"],"mappings":"AAGA,SAASA,kBAAkB,EAAEC,iBAAiB,QAAQ,mBAAkB;AA+BxE;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASC,kBAAkB,EAChCC,MAAM,EACNC,WAAW,MAAM,EACjBC,MAAM,EACNC,IAAI,EACkB;IACtB,IAAI,CAACA,MAAMC,MAAM;QACf,OAAOC;IACT;IAEA,MAAMC,QAAQR,kBAAkB;QAAEE;QAAQO,WAAWJ,KAAKC,IAAI;IAAC;IAC/D,OAAOP,mBAAmB;QAAEG;QAAQC;QAAUC;QAAQI;IAAM;AAC9D"}
+4
View File
@@ -0,0 +1,4 @@
export { getSystemPagePath } from './getSystemPagePath.js';
export { buildSystemPagesFields } from './systemPagesFields.js';
export type { PagesOption, SystemPageRole } from './types.js';
export { ALL_SYSTEM_PAGE_ROLES } from './types.js';
+5
View File
@@ -0,0 +1,5 @@
export { getSystemPagePath } from './getSystemPagePath.js';
export { buildSystemPagesFields } from './systemPagesFields.js';
export { ALL_SYSTEM_PAGE_ROLES } from './types.js';
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/modules/pages/index.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,yBAAwB;AAC1D,SAASC,sBAAsB,QAAQ,yBAAwB;AAE/D,SAASC,qBAAqB,QAAQ,aAAY"}
+12
View File
@@ -0,0 +1,12 @@
import type { Field } from 'payload';
import type { PagesOption } from './types.js';
/**
* 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 declare function buildSystemPagesFields(pages: PagesOption): Field[];
+36
View File
@@ -0,0 +1,36 @@
import { ALL_SYSTEM_PAGE_ROLES } from './types.js';
/** Admin-facing labels per role. */ const ROLE_LABELS = {
cookiePolicy: 'Cookie Policy',
homepage: 'Homepage',
privacyPolicy: 'Privacy Policy'
};
/** 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.'
};
/**
* 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 function buildSystemPagesFields(pages) {
const roles = pages.roles?.length ? pages.roles : [
...ALL_SYSTEM_PAGE_ROLES
];
return roles.map((role)=>({
name: role,
type: 'relationship',
admin: {
description: ROLE_DESCRIPTIONS[role]
},
label: ROLE_LABELS[role],
maxDepth: 1,
relationTo: pages.slug
}));
}
//# sourceMappingURL=systemPagesFields.js.map
+1
View File
@@ -0,0 +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<SystemPageRole, string> = {\n cookiePolicy: 'Cookie Policy',\n homepage: 'Homepage',\n privacyPolicy: 'Privacy Policy',\n}\n\n/** Admin descriptions per role. */\nconst ROLE_DESCRIPTIONS: Record<SystemPageRole, string> = {\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"}
+26
View File
@@ -0,0 +1,26 @@
/**
* 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';
/**
* All system roles in a stable order (used when no subset is configured).
*/
export declare const ALL_SYSTEM_PAGE_ROLES: readonly SystemPageRole[];
/**
* 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 type PagesOption = {
/**
* Which system roles to expose as assignable fields.
* Defaults to all roles when omitted.
*/
roles?: SystemPageRole[];
/** Slug of the client's Pages collection, e.g. 'pages'. */
slug: string;
};
+12
View File
@@ -0,0 +1,12 @@
/**
* Built-in "system page" roles — documents from the client's Pages
* collection that the site references by function rather than by slug.
*/ /**
* All system roles in a stable order (used when no subset is configured).
*/ export const ALL_SYSTEM_PAGE_ROLES = [
'homepage',
'privacyPolicy',
'cookiePolicy'
];
//# sourceMappingURL=types.js.map
+1
View File
@@ -0,0 +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"}