@kilivi/payloadcms-theme-management 1.1.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +81 -4
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiD,MAAM,EAAa,MAAM,SAAS,CAAA;AAG/F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C,OAAO,KAAK,EACV,8BAA8B,EAG9B,4BAA4B,EAC7B,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiD,MAAM,EAAa,MAAM,SAAS,CAAA;AAG/F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C,OAAO,KAAK,EACV,8BAA8B,EAG9B,4BAA4B,EAC7B,MAAM,YAAY,CAAA;AA0nBnB,eAAO,MAAM,qBAAqB,GAAI,UAAS,4BAAiC,KAAG,MAyOlF,CAAA;AAED,KAAK,iBAAiB,GAAG,MAAM,GAAG,8BAA8B,CAAA;AAEhE,eAAO,MAAM,uBAAuB,GAClC,UAAU,iBAAiB,KAC1B,OAAO,CAAC,sBAAsB,GAAG,IAAI,CA6EvC,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,WAAW,MAAM,KAAG,WAAW,GAAG,IAEhE,CAAA;AAED,eAAO,MAAM,wBAAwB,QAAO,WAAW,EAEtD,CAAA;AAED,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACnE,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACtE,YAAY,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAA;AACnE,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,2BAA2B,GAC5B,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACnF,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,iCAAiC,CAAA;AACxC,YAAY,EACV,4BAA4B,EAC5B,uCAAuC,EACvC,8BAA8B,EAC9B,iCAAiC,EACjC,iCAAiC,GAClC,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,sCAAsC,CAAA;AAC7C,YAAY,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAA;AACtF,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAGvE,OAAO,EACL,gBAAgB,IAAI,iBAAiB,EACrC,oBAAoB,GACrB,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAEhF,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAG1D,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,eAAe,GAChB,MAAM,4BAA4B,CAAA;AAMnC,eAAO,MAAM,qBAAqB,aA9Xa,4BAA4B,KAAQ,MA8XzB,CAAA;AAC1D,oDAAoD;AACpD,eAAO,MAAM,wBAAwB,aAhYU,4BAA4B,KAAQ,MAgYtB,CAAA;AAG7D,OAAO,EACL,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,mBAAmB,CAAA;AAE1B,eAAe,qBAAqB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -84,6 +84,8 @@ const normalizeLivePreviewOptions = (livePreview)=>{
|
|
|
84
84
|
if (livePreview === false) {
|
|
85
85
|
return {
|
|
86
86
|
enabled: false,
|
|
87
|
+
injectRoute: false,
|
|
88
|
+
routePath: '/theme/preview',
|
|
87
89
|
pageCollection: 'pages',
|
|
88
90
|
pageSlug: 'home',
|
|
89
91
|
fallbackToFirstPage: true,
|
|
@@ -95,6 +97,8 @@ const normalizeLivePreviewOptions = (livePreview)=>{
|
|
|
95
97
|
const raw = typeof livePreview === 'object' && livePreview ? livePreview : {};
|
|
96
98
|
return {
|
|
97
99
|
enabled: raw.enabled ?? true,
|
|
100
|
+
injectRoute: raw.injectRoute ?? false,
|
|
101
|
+
routePath: normalizeRoutePath(raw.routePath),
|
|
98
102
|
pageCollection: raw.pageCollection ?? 'pages',
|
|
99
103
|
pageSlug: raw.pageSlug ?? 'home',
|
|
100
104
|
fallbackToFirstPage: raw.fallbackToFirstPage ?? true,
|
|
@@ -312,6 +316,68 @@ const executeThemeRevalidation = async (options)=>{
|
|
|
312
316
|
paths
|
|
313
317
|
};
|
|
314
318
|
};
|
|
319
|
+
const readQueryStringFromRequest = (req, paramName)=>{
|
|
320
|
+
const reqRecord = asRecord(req);
|
|
321
|
+
// Try URLSearchParams from native fetch/Node.js
|
|
322
|
+
const queryValue = reqRecord?.query;
|
|
323
|
+
if (queryValue && typeof URLSearchParams !== 'undefined' && queryValue instanceof URLSearchParams) {
|
|
324
|
+
return pickString(queryValue.get(paramName));
|
|
325
|
+
}
|
|
326
|
+
// Try object form (common in Payload)
|
|
327
|
+
const queryRecord = asRecord(queryValue);
|
|
328
|
+
if (queryRecord) {
|
|
329
|
+
const rawValue = queryRecord[paramName];
|
|
330
|
+
if (Array.isArray(rawValue)) {
|
|
331
|
+
return pickString(rawValue[0]);
|
|
332
|
+
}
|
|
333
|
+
return pickString(rawValue);
|
|
334
|
+
}
|
|
335
|
+
// Try manual URL parsing as fallback
|
|
336
|
+
const urlValue = pickString(reqRecord?.url) ?? pickString(reqRecord?.originalUrl);
|
|
337
|
+
if (urlValue) {
|
|
338
|
+
try {
|
|
339
|
+
const url = new URL(urlValue, 'http://localhost');
|
|
340
|
+
return pickString(url.searchParams.get(paramName));
|
|
341
|
+
} catch {
|
|
342
|
+
// Ignore parse errors
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return undefined;
|
|
346
|
+
};
|
|
347
|
+
const createLivePreviewEndpoint = (options)=>{
|
|
348
|
+
const { livePreview, enableLogging } = options;
|
|
349
|
+
if (!livePreview.enabled || !livePreview.injectRoute) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
path: livePreview.routePath,
|
|
354
|
+
method: 'get',
|
|
355
|
+
handler: async (req)=>{
|
|
356
|
+
const previewSecret = process.env.PREVIEW_SECRET ?? process.env.PAYLOAD_PREVIEW_SECRET;
|
|
357
|
+
if (previewSecret) {
|
|
358
|
+
const providedSecret = readQueryStringFromRequest(req, 'previewSecret') ?? readQueryStringFromRequest(req, 'preview');
|
|
359
|
+
if (providedSecret !== previewSecret) {
|
|
360
|
+
return jsonResponse({
|
|
361
|
+
error: 'Unauthorized'
|
|
362
|
+
}, 401);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
const pageSlug = readQueryStringFromRequest(req, 'pageSlug') ?? livePreview.pageSlug;
|
|
366
|
+
const tenantSlug = readQueryStringFromRequest(req, 'tenant');
|
|
367
|
+
// Redirect to the actual client page (standard Payload live preview behavior)
|
|
368
|
+
const destination = buildDefaultPreviewPath(pageSlug, tenantSlug, livePreview.tenantQueryParam);
|
|
369
|
+
if (enableLogging) {
|
|
370
|
+
console.log('🎨 Theme Management Plugin: live preview redirect', destination);
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
status: 307,
|
|
374
|
+
headers: {
|
|
375
|
+
Location: destination
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
};
|
|
315
381
|
const createCacheRevalidationEndpoint = (options)=>{
|
|
316
382
|
const { cacheRevalidation, enableLogging } = options;
|
|
317
383
|
if (!cacheRevalidation.enabled || !cacheRevalidation.injectRoute) {
|
|
@@ -356,9 +422,10 @@ const mergeEndpoint = (endpoints, endpoint)=>{
|
|
|
356
422
|
if (!endpoint) {
|
|
357
423
|
return endpoints;
|
|
358
424
|
}
|
|
425
|
+
const record = endpoint;
|
|
359
426
|
const withoutExisting = endpoints.filter((candidate)=>{
|
|
360
|
-
const
|
|
361
|
-
return !(
|
|
427
|
+
const candidateRecord = candidate;
|
|
428
|
+
return !(candidateRecord?.path === record?.path && typeof candidateRecord.method === 'string' && typeof record.method === 'string' && candidateRecord.method.toLowerCase() === record.method.toLowerCase());
|
|
362
429
|
});
|
|
363
430
|
return [
|
|
364
431
|
...withoutExisting,
|
|
@@ -491,11 +558,16 @@ export const themeManagementPlugin = (options = {})=>{
|
|
|
491
558
|
return config;
|
|
492
559
|
}
|
|
493
560
|
const currentEndpoints = ensureEndpointsArray(config.endpoints);
|
|
561
|
+
const livePreviewEndpoint = createLivePreviewEndpoint({
|
|
562
|
+
livePreview: normalizedLivePreview,
|
|
563
|
+
enableLogging
|
|
564
|
+
});
|
|
565
|
+
let endpoints = mergeEndpoint(currentEndpoints, livePreviewEndpoint);
|
|
494
566
|
const cacheEndpoint = createCacheRevalidationEndpoint({
|
|
495
567
|
cacheRevalidation: normalizedCacheRevalidation,
|
|
496
568
|
enableLogging
|
|
497
569
|
});
|
|
498
|
-
|
|
570
|
+
endpoints = mergeEndpoint(endpoints, cacheEndpoint);
|
|
499
571
|
return {
|
|
500
572
|
...config,
|
|
501
573
|
endpoints,
|
|
@@ -534,11 +606,16 @@ export const themeManagementPlugin = (options = {})=>{
|
|
|
534
606
|
return config;
|
|
535
607
|
}
|
|
536
608
|
const currentEndpoints = ensureEndpointsArray(config.endpoints);
|
|
609
|
+
const livePreviewEndpoint = createLivePreviewEndpoint({
|
|
610
|
+
livePreview: normalizedLivePreview,
|
|
611
|
+
enableLogging
|
|
612
|
+
});
|
|
613
|
+
let endpoints = mergeEndpoint(currentEndpoints, livePreviewEndpoint);
|
|
537
614
|
const cacheEndpoint = createCacheRevalidationEndpoint({
|
|
538
615
|
cacheRevalidation: normalizedCacheRevalidation,
|
|
539
616
|
enableLogging
|
|
540
617
|
});
|
|
541
|
-
|
|
618
|
+
endpoints = mergeEndpoint(endpoints, cacheEndpoint);
|
|
542
619
|
return {
|
|
543
620
|
...config,
|
|
544
621
|
endpoints,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config, Field, GlobalConfig, Plugin, TabsField } from 'payload'\nimport { createThemeConfigurationField } from './fields/themeConfigurationField.js'\nimport type { ThemeTab } from './fields/themeConfigurationField.js'\nimport type { SiteThemeConfiguration } from './payload-types.js'\nimport type { ThemePreset } from './presets.js'\nimport { allThemePresets } from './presets.js'\nimport { getTranslations, translations } from './translations.js'\nimport type {\n FetchThemeConfigurationOptions,\n ThemeManagementLivePreviewOptions,\n ThemeManagementLivePreviewUrlArgs,\n ThemeManagementPluginOptions,\n} from './types.js'\n\nconst THEME_FIELD_NAME = 'themeConfiguration'\n\n/**\n * Removes existing theme configuration from a group field (legacy)\n */\nconst removeExistingThemeField = (fields: Field[] = []): Field[] =>\n fields.filter((field) => {\n const candidate = field as { name?: unknown }\n return candidate?.name !== THEME_FIELD_NAME\n })\n\n/**\n * Finds the tabs field in the collection fields array\n */\nconst findTabsField = (fields: Field[] = []): TabsField | null => {\n for (const field of fields) {\n if (field.type === 'tabs') {\n return field as TabsField\n }\n }\n return null\n}\n\n/**\n * Removes existing Appearance Settings tab if it exists\n */\nconst removeExistingThemeTab = (\n tabs: NonNullable<TabsField['tabs']>,\n): NonNullable<TabsField['tabs']> => {\n const knownLabels = Object.values(translations).map((t) => t.tabLabel)\n return tabs.filter((tab) => {\n // Normalize label to string (support localized object or plain string)\n let labelValues: string[] = []\n if (typeof tab.label === 'object' && tab.label !== null) {\n labelValues = Object.values(tab.label as Record<string, string>)\n } else if (typeof tab.label === 'string') {\n labelValues = [tab.label]\n }\n\n // If any of the label values match a known plugin tab label, remove it\n const matchesKnown = labelValues.some((v) => knownLabels.includes(v))\n\n return !matchesKnown\n })\n}\n\n/**\n * Injects theme tab into existing tabs field\n */\nconst injectThemeTab = (\n fields: Field[] | undefined,\n themeTab: ThemeTab,\n enableLogging: boolean,\n): Field[] => {\n // First, remove any legacy theme field (group-based)\n const sanitizedFields = removeExistingThemeField(fields ?? [])\n\n // Find the tabs field\n const tabsField = findTabsField(sanitizedFields)\n\n if (!tabsField || !tabsField.tabs) {\n if (enableLogging) {\n console.warn(\n '🎨 Theme Management Plugin: No tabs field found. Creating a new tabs structure.',\n )\n }\n\n // If no tabs exist, create a basic tabs structure with just the theme tab\n const newTabsField: TabsField = {\n type: 'tabs',\n tabs: [themeTab],\n }\n\n return [...sanitizedFields, newTabsField]\n }\n\n // Remove existing theme tab if present\n const sanitizedTabs = removeExistingThemeTab(tabsField.tabs)\n\n // Add theme tab to the end\n const updatedTabs = [...sanitizedTabs, themeTab]\n\n if (enableLogging) {\n console.log('🎨 Theme Management Plugin: injecting Appearance Settings tab')\n }\n\n // Update the tabs field\n const updatedTabsField: TabsField = {\n ...tabsField,\n tabs: updatedTabs,\n }\n\n // Replace the old tabs field with the updated one\n return sanitizedFields.map((field) => (field.type === 'tabs' ? updatedTabsField : field))\n}\n\nconst ensureCollectionsArray = (collections: Config['collections']): CollectionConfig[] =>\n Array.isArray(collections) ? collections : []\n\nconst ensureEndpointsArray = (endpoints: Config['endpoints']): NonNullable<Config['endpoints']> =>\n Array.isArray(endpoints) ? endpoints : []\n\ntype NormalizedLivePreviewOptions = {\n enabled: boolean\n pageCollection: string\n pageSlug: string\n fallbackToFirstPage: boolean\n tenantField: string\n tenantQueryParam: string\n breakpoints?: ThemeManagementLivePreviewOptions['breakpoints']\n url?: ThemeManagementLivePreviewOptions['url']\n}\n\ntype NormalizedCacheRevalidationOptions = {\n enabled: boolean\n injectRoute: boolean\n routePath: string\n secret?: string\n tags: string[]\n paths: string[]\n}\n\ntype MinimalPayloadRequest = ThemeManagementLivePreviewUrlArgs['req']\n\nconst normalizeLivePreviewOptions = (\n livePreview: ThemeManagementPluginOptions['livePreview'],\n): NormalizedLivePreviewOptions => {\n if (livePreview === false) {\n return {\n enabled: false,\n pageCollection: 'pages',\n pageSlug: 'home',\n fallbackToFirstPage: true,\n tenantField: 'tenant',\n tenantQueryParam: 'tenant',\n breakpoints: undefined,\n }\n }\n\n const raw = typeof livePreview === 'object' && livePreview ? livePreview : {}\n\n return {\n enabled: raw.enabled ?? true,\n pageCollection: raw.pageCollection ?? 'pages',\n pageSlug: raw.pageSlug ?? 'home',\n fallbackToFirstPage: raw.fallbackToFirstPage ?? true,\n tenantField: raw.tenantField ?? 'tenant',\n tenantQueryParam: raw.tenantQueryParam ?? 'tenant',\n breakpoints: raw.breakpoints,\n url: raw.url,\n }\n}\n\nconst dedupeStrings = (values: (string | undefined)[]): string[] => [\n ...new Set(\n values.filter((value): value is string => typeof value === 'string' && value.trim().length > 0),\n ),\n]\n\nconst normalizeRoutePath = (path: string | undefined): string => {\n if (!path || !path.trim()) {\n return '/theme/revalidate'\n }\n\n return path.startsWith('/') ? path : `/${path}`\n}\n\nconst normalizeCacheRevalidationOptions = (args: {\n cacheRevalidation: ThemeManagementPluginOptions['cacheRevalidation']\n standaloneCollectionSlug: string\n useStandaloneCollection: boolean\n}): NormalizedCacheRevalidationOptions => {\n const { cacheRevalidation, standaloneCollectionSlug, useStandaloneCollection } = args\n\n if (cacheRevalidation === false) {\n return {\n enabled: false,\n injectRoute: false,\n routePath: '/theme/revalidate',\n tags: [],\n paths: [],\n }\n }\n\n const raw = typeof cacheRevalidation === 'object' && cacheRevalidation ? cacheRevalidation : {}\n const defaultTag = `global_${standaloneCollectionSlug}`\n\n return {\n enabled: raw.enabled ?? useStandaloneCollection,\n injectRoute: raw.injectRoute ?? true,\n routePath: normalizeRoutePath(raw.routePath),\n secret: raw.secret,\n tags: dedupeStrings([defaultTag, ...(raw.tags ?? [])]),\n paths: dedupeStrings(raw.paths ?? []),\n }\n}\n\nconst asRecord = (value: unknown): Record<string, unknown> | undefined => {\n if (value && typeof value === 'object') {\n return value as Record<string, unknown>\n }\n return undefined\n}\n\nconst pickString = (value: unknown): string | undefined => {\n if (typeof value === 'string' && value.trim()) return value\n return undefined\n}\n\nconst extractTenantValue = (value: unknown): string | undefined => {\n if (!value) return undefined\n if (typeof value === 'string') return pickString(value)\n\n const tenantRecord = asRecord(value)\n if (!tenantRecord) return undefined\n\n return (\n pickString(tenantRecord.id) ??\n pickString(tenantRecord.slug) ??\n pickString(tenantRecord.value) ??\n pickString(tenantRecord.tenant)\n )\n}\n\nconst resolveTenantSlug = (\n req: MinimalPayloadRequest,\n tenantField: string,\n data?: Record<string, unknown>,\n): string | undefined => {\n const fromData = extractTenantValue(data?.[tenantField])\n if (fromData) return fromData\n\n const query = req.query\n if (query && typeof URLSearchParams !== 'undefined' && query instanceof URLSearchParams) {\n return (\n pickString(query.get('tenant')) ??\n pickString(query.get('tenantSlug')) ??\n pickString(query.get('tenantId'))\n )\n }\n\n const queryRecord = asRecord(query)\n const fromQuery =\n extractTenantValue(queryRecord?.tenant) ??\n extractTenantValue(queryRecord?.tenantSlug) ??\n extractTenantValue(queryRecord?.tenantId)\n if (fromQuery) return fromQuery\n\n const userRecord = asRecord(req.user)\n const fromUser =\n extractTenantValue(userRecord?.[tenantField]) ??\n extractTenantValue(userRecord?.tenant) ??\n extractTenantValue(userRecord?.tenantSlug)\n if (fromUser) return fromUser\n\n const headers = req.headers\n if (headers && typeof Headers !== 'undefined' && headers instanceof Headers) {\n return (\n pickString(headers.get('x-tenant-id')) ??\n pickString(headers.get('x-tenant')) ??\n pickString(headers.get('payload-tenant'))\n )\n }\n\n const headerRecord = asRecord(headers)\n return (\n extractTenantValue(headerRecord?.['x-tenant-id']) ??\n extractTenantValue(headerRecord?.['x-tenant']) ??\n extractTenantValue(headerRecord?.['payload-tenant'])\n )\n}\n\nconst buildDefaultPreviewPath = (\n pageSlug: string,\n tenantSlug: string | undefined,\n tenantQueryParam: string,\n): string => {\n const normalizedSlug = pageSlug === 'home' ? '' : pageSlug\n const basePath = normalizedSlug ? `/${normalizedSlug}` : '/'\n\n if (!tenantSlug) {\n return basePath\n }\n\n const separator = basePath.includes('?') ? '&' : '?'\n return `${basePath}${separator}${tenantQueryParam}=${encodeURIComponent(tenantSlug)}`\n}\n\nconst resolveLivePreviewUrl = async (args: {\n req: MinimalPayloadRequest\n data?: Record<string, unknown>\n livePreview: NormalizedLivePreviewOptions\n enableLogging: boolean\n}): Promise<string> => {\n const { req, data, livePreview, enableLogging } = args\n\n const tenantSlug = resolveTenantSlug(req, livePreview.tenantField, data)\n\n const tenantWhere = tenantSlug\n ? {\n [livePreview.tenantField]: {\n equals: tenantSlug,\n },\n }\n : undefined\n\n const homeWhere = {\n and: [\n {\n slug: {\n equals: livePreview.pageSlug,\n },\n },\n ...(tenantWhere ? [tenantWhere] : []),\n ],\n }\n\n try {\n const preferredPageResponse = await req.payload.find({\n collection: livePreview.pageCollection,\n where: homeWhere,\n depth: 0,\n draft: true,\n limit: 1,\n overrideAccess: true,\n pagination: false,\n })\n\n let page = preferredPageResponse?.docs?.[0]\n\n if (!page && livePreview.fallbackToFirstPage) {\n const fallbackResponse = await req.payload.find({\n collection: livePreview.pageCollection,\n where: tenantWhere,\n depth: 0,\n draft: true,\n limit: 1,\n overrideAccess: true,\n pagination: false,\n })\n\n page = fallbackResponse?.docs?.[0]\n }\n\n const pageRecord = asRecord(page)\n const resolvedPageSlug = pickString(pageRecord?.slug) ?? livePreview.pageSlug\n\n if (livePreview.url) {\n return await livePreview.url({\n page: pageRecord,\n pageSlug: resolvedPageSlug,\n tenantSlug,\n req,\n })\n }\n\n return buildDefaultPreviewPath(resolvedPageSlug, tenantSlug, livePreview.tenantQueryParam)\n } catch (error) {\n if (enableLogging) {\n req.payload.logger?.warn?.(\n '🎨 Theme Management Plugin: live preview URL fallback used',\n error,\n )\n }\n\n return buildDefaultPreviewPath(livePreview.pageSlug, tenantSlug, livePreview.tenantQueryParam)\n }\n}\n\nconst createPreviewAdminConfig = (\n normalizedLivePreview: NormalizedLivePreviewOptions,\n enableLogging: boolean,\n) => {\n if (!normalizedLivePreview.enabled) {\n return {}\n }\n\n return {\n livePreview: {\n breakpoints: normalizedLivePreview.breakpoints,\n url: ({ data, req }: { data?: unknown; req: unknown }) =>\n resolveLivePreviewUrl({\n req: req as MinimalPayloadRequest,\n data: asRecord(data),\n livePreview: normalizedLivePreview,\n enableLogging,\n }),\n },\n preview: (data: Record<string, unknown>, options: { req?: unknown }) => {\n const req = options?.req\n if (!req) return null\n\n return resolveLivePreviewUrl({\n req: req as MinimalPayloadRequest,\n data,\n livePreview: normalizedLivePreview,\n enableLogging,\n })\n },\n }\n}\n\nconst readSecretFromRequest = async (req: unknown): Promise<string | undefined> => {\n const requestRecord = asRecord(req)\n const headersValue = requestRecord?.headers\n\n if (headersValue && typeof Headers !== 'undefined' && headersValue instanceof Headers) {\n return (\n pickString(headersValue.get('x-theme-revalidate-secret')) ??\n pickString(headersValue.get('x-revalidate-secret'))\n )\n }\n\n const headerRecord = asRecord(headersValue)\n const fromHeaders =\n pickString(headerRecord?.['x-theme-revalidate-secret']) ??\n pickString(headerRecord?.['x-revalidate-secret'])\n if (fromHeaders) {\n return fromHeaders\n }\n\n const requestWithJson = req as { json?: () => Promise<unknown> }\n const body =\n typeof requestWithJson?.json === 'function' ? await requestWithJson.json() : undefined\n const bodyRecord = asRecord(body)\n const fromBody = pickString(bodyRecord?.secret)\n if (fromBody) {\n return fromBody\n }\n\n const queryRecord = asRecord(requestRecord?.query)\n return pickString(queryRecord?.secret)\n}\n\nconst executeThemeRevalidation = async (options: {\n tags: string[]\n paths: string[]\n enableLogging: boolean\n logger?: { info?: (...args: any[]) => void; error?: (...args: any[]) => void }\n}): Promise<{ tags: string[]; paths: string[] }> => {\n const { tags, paths, enableLogging, logger } = options\n\n try {\n const { revalidatePath, revalidateTag } = await import('next/cache')\n\n tags.forEach((tag) => revalidateTag(tag))\n paths.forEach((path) => revalidatePath(path))\n\n if (enableLogging) {\n logger?.info?.(\n `🎨 Theme Management Plugin: revalidated cache tags=[${tags.join(', ')}] paths=[${paths.join(', ')}]`,\n )\n }\n } catch (error) {\n if (enableLogging) {\n logger?.error?.('🎨 Theme Management Plugin: cache invalidation failed:', error)\n }\n throw error\n }\n\n return { tags, paths }\n}\n\nconst createCacheRevalidationEndpoint = (options: {\n cacheRevalidation: NormalizedCacheRevalidationOptions\n enableLogging: boolean\n}) => {\n const { cacheRevalidation, enableLogging } = options\n\n if (!cacheRevalidation.enabled || !cacheRevalidation.injectRoute) {\n return null\n }\n\n return {\n path: cacheRevalidation.routePath,\n method: 'post',\n handler: async (req: unknown) => {\n const reqRecord = asRecord(req)\n const payload = asRecord(reqRecord?.payload)\n const logger = payload?.logger as\n | { info?: (...args: any[]) => void; error?: (...args: any[]) => void }\n | undefined\n\n if (cacheRevalidation.secret) {\n const providedSecret = await readSecretFromRequest(req)\n if (providedSecret !== cacheRevalidation.secret) {\n return jsonResponse({ error: 'Unauthorized' }, 401)\n }\n }\n\n try {\n const result = await executeThemeRevalidation({\n tags: cacheRevalidation.tags,\n paths: cacheRevalidation.paths,\n enableLogging,\n logger,\n })\n\n return jsonResponse({ ok: true, revalidated: result })\n } catch {\n return jsonResponse({ ok: false, error: 'Revalidation failed' }, 500)\n }\n },\n }\n}\n\nconst mergeEndpoint = (\n endpoints: NonNullable<Config['endpoints']>,\n endpoint: ReturnType<typeof createCacheRevalidationEndpoint>,\n): NonNullable<Config['endpoints']> => {\n if (!endpoint) {\n return endpoints\n }\n\n const withoutExisting = endpoints.filter((candidate) => {\n const record = candidate as unknown as { path?: string; method?: string }\n return !(\n record?.path === endpoint.path &&\n typeof record.method === 'string' &&\n record.method.toLowerCase() === endpoint.method\n )\n })\n\n return [...withoutExisting, endpoint as unknown as NonNullable<Config['endpoints']>[number]]\n}\n\nconst jsonResponse = (body: Record<string, unknown>, status = 200): unknown => {\n if (typeof Response !== 'undefined' && typeof Response.json === 'function') {\n return Response.json(body, { status })\n }\n\n return {\n status,\n json: async () => body,\n }\n}\n\nexport const themeManagementPlugin = (options: ThemeManagementPluginOptions = {}): Plugin => {\n return (config: Config): Config => {\n const {\n enabled = true,\n targetCollection = 'site-settings',\n useStandaloneCollection = false,\n standaloneCollectionSlug = 'appearance-settings',\n // Allow either string or localized object; default comes from plugin translations\n standaloneCollectionLabel = getTranslations().standaloneCollectionLabel,\n themePresets = allThemePresets,\n defaultTheme = 'cool',\n includeColorModeToggle = true,\n includeCustomCSS = true,\n includeBrandIdentity = false,\n enableAdvancedFeatures = true,\n enableLogging = false,\n livePreview = true,\n cacheRevalidation,\n } = options\n\n const normalizedLivePreview = normalizeLivePreviewOptions(livePreview)\n const normalizedCacheRevalidation = normalizeCacheRevalidationOptions({\n cacheRevalidation,\n standaloneCollectionSlug,\n useStandaloneCollection,\n })\n\n if (!enabled) {\n if (enableLogging) {\n console.log('🎨 Theme Management Plugin: disabled via options, skipping.')\n }\n return config\n }\n\n const themeTab = createThemeConfigurationField({\n themePresets,\n defaultTheme,\n includeColorModeToggle,\n includeCustomCSS,\n includeBrandIdentity: includeBrandIdentity ?? false,\n enableAdvancedFeatures,\n useThemePreviewField: !normalizedLivePreview.enabled,\n })\n\n // If using standalone collection, create a new global\n if (useStandaloneCollection) {\n if (enableLogging) {\n console.log(\n `🎨 Theme Management Plugin: creating standalone global \"${standaloneCollectionSlug}\"`,\n )\n }\n\n // Extract the fields from the tab directly (no wrapping in group)\n const tabFields = (themeTab.fields ?? []) as Field[]\n\n /**\n * Hook to auto-populate lightMode and darkMode colors when theme changes\n */\n type BeforeChangeArgs = {\n data?: {\n themeConfiguration?: {\n theme?: string\n lightMode?: Record<string, unknown>\n darkMode?: Record<string, unknown>\n }\n }\n }\n\n const beforeChangeHook = async (args: BeforeChangeArgs) => {\n const { data } = args\n\n // If theme is being changed, auto-populate color modes\n if (data?.themeConfiguration?.theme) {\n const themeName = data.themeConfiguration.theme\n const selectedPreset = themePresets.find((p) => p.name === themeName)\n\n if (selectedPreset) {\n // Initialize light and dark mode colors from preset if not already set\n if (!data.themeConfiguration.lightMode) {\n data.themeConfiguration.lightMode = {}\n }\n if (!data.themeConfiguration.darkMode) {\n data.themeConfiguration.darkMode = {}\n }\n\n // Only populate if not manually edited (first time or empty)\n const isLightModeEmpty = !data.themeConfiguration.lightMode?.background\n const isDarkModeEmpty = !data.themeConfiguration.darkMode?.background\n\n if (isLightModeEmpty && selectedPreset.lightMode) {\n data.themeConfiguration.lightMode = { ...selectedPreset.lightMode }\n }\n\n if (isDarkModeEmpty && selectedPreset.darkMode) {\n data.themeConfiguration.darkMode = { ...selectedPreset.darkMode }\n }\n }\n }\n\n return data\n }\n\n const standaloneGlobal: GlobalConfig = {\n slug: standaloneCollectionSlug,\n label: standaloneCollectionLabel,\n admin: {\n group: 'Settings',\n ...createPreviewAdminConfig(normalizedLivePreview, enableLogging),\n },\n // Provide a broad access object but cast to GlobalConfig['access'] to satisfy types\n access: ((): GlobalConfig['access'] => {\n const accessObj = {\n read: () => true,\n create: ({ req }: { req?: { user?: unknown } }) => !!req?.user,\n update: ({ req }: { req?: { user?: unknown } }) => !!req?.user,\n delete: ({ req }: { req?: { user?: unknown } }) => !!req?.user,\n } as unknown as GlobalConfig['access']\n return accessObj\n })(),\n fields: tabFields,\n hooks: {\n beforeChange: [beforeChangeHook],\n afterChange: [\n async ({ doc, req }) => {\n // Invalidate cache after appearance settings change\n if (!req?.context?.disableRevalidate && normalizedCacheRevalidation.enabled) {\n try {\n await executeThemeRevalidation({\n tags: normalizedCacheRevalidation.tags,\n paths: normalizedCacheRevalidation.paths,\n enableLogging,\n logger: req?.payload?.logger,\n })\n } catch {\n // no-op: logging is handled in executeThemeRevalidation\n }\n }\n return doc\n },\n ],\n },\n }\n\n const globals = Array.isArray(config.globals) ? config.globals : []\n\n // Check if global already exists\n const existingIndex = globals.findIndex((g) => g.slug === standaloneCollectionSlug)\n\n if (existingIndex !== -1) {\n if (enableLogging) {\n console.warn(\n `🎨 Theme Management Plugin: global \"${standaloneCollectionSlug}\" already exists, skipping creation.`,\n )\n }\n return config\n }\n\n const currentEndpoints = ensureEndpointsArray(config.endpoints)\n const cacheEndpoint = createCacheRevalidationEndpoint({\n cacheRevalidation: normalizedCacheRevalidation,\n enableLogging,\n })\n const endpoints = mergeEndpoint(currentEndpoints, cacheEndpoint)\n\n return {\n ...config,\n endpoints,\n globals: [...globals, standaloneGlobal],\n }\n }\n\n // Otherwise, add as tab to existing collection\n let collectionTouched = false\n\n const collections = ensureCollectionsArray(config.collections).map((collection) => {\n if (collection.slug !== targetCollection) {\n return collection\n }\n\n collectionTouched = true\n\n if (enableLogging) {\n console.log(`🎨 Theme Management Plugin: enhancing collection \"${collection.slug}\"`)\n }\n\n const existingFields = Array.isArray(collection.fields) ? collection.fields : []\n\n const fields = injectThemeTab(existingFields, themeTab, enableLogging)\n\n const admin = {\n ...collection.admin,\n ...createPreviewAdminConfig(normalizedLivePreview, enableLogging),\n }\n\n return {\n ...collection,\n fields,\n admin,\n }\n })\n\n if (!collectionTouched) {\n if (enableLogging) {\n console.warn(\n `🎨 Theme Management Plugin: collection \"${targetCollection}\" was not found, leaving config untouched.`,\n )\n }\n return config\n }\n\n const currentEndpoints = ensureEndpointsArray(config.endpoints)\n const cacheEndpoint = createCacheRevalidationEndpoint({\n cacheRevalidation: normalizedCacheRevalidation,\n enableLogging,\n })\n const endpoints = mergeEndpoint(currentEndpoints, cacheEndpoint)\n\n return {\n ...config,\n endpoints,\n collections,\n }\n }\n}\n\ntype FetchOptionsInput = string | FetchThemeConfigurationOptions\n\nexport const fetchThemeConfiguration = async (\n options?: FetchOptionsInput,\n): Promise<SiteThemeConfiguration | null> => {\n const normalizedOptions = typeof options === 'string' ? { tenantSlug: options } : (options ?? {})\n\n const {\n tenantSlug,\n collectionSlug = 'site-settings', // Can be overridden to 'appearance-settings' if using standalone\n depth,\n locale,\n draft,\n queryParams = {},\n useGlobal = false, // Set to true if using standalone global instead of collection\n } = normalizedOptions\n\n try {\n if (useGlobal) {\n // Fetch from global endpoint\n const params = new URLSearchParams()\n\n if (typeof depth === 'number') params.set('depth', String(depth))\n // For globals, keep tenant param for backwards compatibility, and also add where[...] filter\n if (tenantSlug) {\n params.set('tenant', tenantSlug)\n params.set('where[tenant][equals]', String(tenantSlug))\n }\n\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value === undefined) return\n params.set(key, String(value))\n })\n\n const queryString = params.toString()\n const url = `/api/globals/${collectionSlug}${queryString ? `?${queryString}` : ''}`\n\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch theme global (status ${response.status})`)\n }\n\n const data = (await response.json()) as {\n themeConfiguration?: SiteThemeConfiguration\n }\n\n return data?.themeConfiguration ?? null\n } else {\n // Fetch from collection endpoint (legacy/default behavior)\n const params = new URLSearchParams({ limit: '1' })\n\n if (typeof depth === 'number') params.set('depth', String(depth))\n // For collections, use a where[tenant][equals] filter so Payload's find endpoint applies tenant scoping\n if (tenantSlug) params.set('where[tenant][equals]', String(tenantSlug))\n if (locale) params.set('locale', locale)\n if (draft) params.set('draft', 'true')\n\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value === undefined) return\n params.set(key, String(value))\n })\n\n const url = `/api/${collectionSlug}?${params.toString()}`\n\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch theme configuration (status ${response.status})`)\n }\n\n const data = (await response.json()) as {\n docs?: Array<{ themeConfiguration?: SiteThemeConfiguration }>\n }\n\n const doc = data.docs?.[0]\n\n return doc?.themeConfiguration ?? null\n }\n } catch (error) {\n console.warn('Failed to fetch theme configuration:', error)\n return null\n }\n}\n\nexport const getThemePreset = (themeName: string): ThemePreset | null => {\n return allThemePresets.find((preset) => preset.name === themeName) || null\n}\n\nexport const getAvailableThemePresets = (): ThemePreset[] => {\n return allThemePresets\n}\n\nexport { defaultThemePresets, allThemePresets } from './presets.js'\nexport type { ThemePreset, ThemeTypographyPreset } from './presets.js'\nexport type { ThemeTab } from './fields/themeConfigurationField.js'\nexport {\n extendedThemePresets,\n allExtendedThemePresets,\n extendedThemeToCSSVariables,\n} from './extended-presets.js'\nexport type { ExtendedThemePreset, ShadcnColorTokens } from './extended-presets.js'\nexport {\n applyExtendedTheme,\n generateExtendedThemeCSS,\n resetExtendedTheme,\n getExtendedThemeTokens,\n createUseExtendedTheme,\n getTailwindVarReferences,\n} from './utils/extendedThemeHelpers.js'\nexport type {\n ThemeManagementPluginOptions,\n ThemeManagementCacheRevalidationOptions,\n FetchThemeConfigurationOptions,\n ThemeManagementLivePreviewOptions,\n ThemeManagementLivePreviewUrlArgs,\n} from './types.js'\nexport {\n DEFAULT_THEME_CONFIGURATION,\n resolveThemeConfiguration,\n} from './utils/resolveThemeConfiguration.js'\nexport type { ResolvedThemeConfiguration } from './utils/resolveThemeConfiguration.js'\nexport { generateThemeColorsCss, hexToHsl } from './utils/themeColors.js'\nexport { generateThemeCSS, getThemeStyles } from './utils/themeUtils.js'\nexport { getThemeHtmlAttributes } from './utils/themeHtmlAttributes.js'\n\n// Dynamic theme CSS generation\nexport {\n generateThemeCSS as generatePresetCSS,\n generateAllThemesCSS,\n} from './utils/generateThemeCSS.js'\nexport { getThemeDynamicCSS, getAllDynamicThemesCSS } from './utils/themeCSS.js'\n\nexport type { Mode, ThemeDefaults } from './providers/Theme/types.js'\nexport { ThemeProvider } from './providers/Theme/index.js'\n\n// Font loading utilities for Next.js integration\nexport {\n getFontLoaderCode,\n getThemeFontFamilies,\n ThemeFontProvider,\n useThemeFonts,\n FONT_IMPORT_MAP,\n} from './providers/font-loader.js'\n\n// Note: Do NOT re-export client components from the root entry to avoid\n// server-side evaluation during `payload generate:importmap`.\n// If needed, import directly from subpath: `@kilivi/payloadcms-theme-management/fields/ThemeLivePreview`\n\nexport const ThemeManagementPlugin = themeManagementPlugin\n/** @deprecated use {@link themeManagementPlugin} */\nexport const themeConfigurationPlugin = themeManagementPlugin\n\n// Export plugin translations for consumers to merge into their payload translations\nexport {\n translations,\n getTranslations,\n registerTranslations,\n availableLanguages,\n} from './translations.js'\n\nexport default themeManagementPlugin\n"],"names":["createThemeConfigurationField","allThemePresets","getTranslations","translations","THEME_FIELD_NAME","removeExistingThemeField","fields","filter","field","candidate","name","findTabsField","type","removeExistingThemeTab","tabs","knownLabels","Object","values","map","t","tabLabel","tab","labelValues","label","matchesKnown","some","v","includes","injectThemeTab","themeTab","enableLogging","sanitizedFields","tabsField","console","warn","newTabsField","sanitizedTabs","updatedTabs","log","updatedTabsField","ensureCollectionsArray","collections","Array","isArray","ensureEndpointsArray","endpoints","normalizeLivePreviewOptions","livePreview","enabled","pageCollection","pageSlug","fallbackToFirstPage","tenantField","tenantQueryParam","breakpoints","undefined","raw","url","dedupeStrings","Set","value","trim","length","normalizeRoutePath","path","startsWith","normalizeCacheRevalidationOptions","args","cacheRevalidation","standaloneCollectionSlug","useStandaloneCollection","injectRoute","routePath","tags","paths","defaultTag","secret","asRecord","pickString","extractTenantValue","tenantRecord","id","slug","tenant","resolveTenantSlug","req","data","fromData","query","URLSearchParams","get","queryRecord","fromQuery","tenantSlug","tenantId","userRecord","user","fromUser","headers","Headers","headerRecord","buildDefaultPreviewPath","normalizedSlug","basePath","separator","encodeURIComponent","resolveLivePreviewUrl","tenantWhere","equals","homeWhere","and","preferredPageResponse","payload","find","collection","where","depth","draft","limit","overrideAccess","pagination","page","docs","fallbackResponse","pageRecord","resolvedPageSlug","error","logger","createPreviewAdminConfig","normalizedLivePreview","preview","options","readSecretFromRequest","requestRecord","headersValue","fromHeaders","requestWithJson","body","json","bodyRecord","fromBody","executeThemeRevalidation","revalidatePath","revalidateTag","forEach","tag","info","join","createCacheRevalidationEndpoint","method","handler","reqRecord","providedSecret","jsonResponse","result","ok","revalidated","mergeEndpoint","endpoint","withoutExisting","record","toLowerCase","status","Response","themeManagementPlugin","config","targetCollection","standaloneCollectionLabel","themePresets","defaultTheme","includeColorModeToggle","includeCustomCSS","includeBrandIdentity","enableAdvancedFeatures","normalizedCacheRevalidation","useThemePreviewField","tabFields","beforeChangeHook","themeConfiguration","theme","themeName","selectedPreset","p","lightMode","darkMode","isLightModeEmpty","background","isDarkModeEmpty","standaloneGlobal","admin","group","access","accessObj","read","create","update","delete","hooks","beforeChange","afterChange","doc","context","disableRevalidate","globals","existingIndex","findIndex","g","currentEndpoints","cacheEndpoint","collectionTouched","existingFields","fetchThemeConfiguration","normalizedOptions","collectionSlug","locale","queryParams","useGlobal","params","set","String","entries","key","queryString","toString","response","fetch","Error","getThemePreset","preset","getAvailableThemePresets","defaultThemePresets","extendedThemePresets","allExtendedThemePresets","extendedThemeToCSSVariables","applyExtendedTheme","generateExtendedThemeCSS","resetExtendedTheme","getExtendedThemeTokens","createUseExtendedTheme","getTailwindVarReferences","DEFAULT_THEME_CONFIGURATION","resolveThemeConfiguration","generateThemeColorsCss","hexToHsl","generateThemeCSS","getThemeStyles","getThemeHtmlAttributes","generatePresetCSS","generateAllThemesCSS","getThemeDynamicCSS","getAllDynamicThemesCSS","ThemeProvider","getFontLoaderCode","getThemeFontFamilies","ThemeFontProvider","useThemeFonts","FONT_IMPORT_MAP","ThemeManagementPlugin","themeConfigurationPlugin","registerTranslations","availableLanguages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config, Field, GlobalConfig, Plugin, TabsField } from 'payload'\nimport { createThemeConfigurationField } from './fields/themeConfigurationField.js'\nimport type { ThemeTab } from './fields/themeConfigurationField.js'\nimport type { SiteThemeConfiguration } from './payload-types.js'\nimport type { ThemePreset } from './presets.js'\nimport { allThemePresets } from './presets.js'\nimport { getTranslations, translations } from './translations.js'\nimport type {\n FetchThemeConfigurationOptions,\n ThemeManagementLivePreviewOptions,\n ThemeManagementLivePreviewUrlArgs,\n ThemeManagementPluginOptions,\n} from './types.js'\n\nconst THEME_FIELD_NAME = 'themeConfiguration'\n\n/**\n * Removes existing theme configuration from a group field (legacy)\n */\nconst removeExistingThemeField = (fields: Field[] = []): Field[] =>\n fields.filter((field) => {\n const candidate = field as { name?: unknown }\n return candidate?.name !== THEME_FIELD_NAME\n })\n\n/**\n * Finds the tabs field in the collection fields array\n */\nconst findTabsField = (fields: Field[] = []): TabsField | null => {\n for (const field of fields) {\n if (field.type === 'tabs') {\n return field as TabsField\n }\n }\n return null\n}\n\n/**\n * Removes existing Appearance Settings tab if it exists\n */\nconst removeExistingThemeTab = (\n tabs: NonNullable<TabsField['tabs']>,\n): NonNullable<TabsField['tabs']> => {\n const knownLabels = Object.values(translations).map((t) => t.tabLabel)\n return tabs.filter((tab) => {\n // Normalize label to string (support localized object or plain string)\n let labelValues: string[] = []\n if (typeof tab.label === 'object' && tab.label !== null) {\n labelValues = Object.values(tab.label as Record<string, string>)\n } else if (typeof tab.label === 'string') {\n labelValues = [tab.label]\n }\n\n // If any of the label values match a known plugin tab label, remove it\n const matchesKnown = labelValues.some((v) => knownLabels.includes(v))\n\n return !matchesKnown\n })\n}\n\n/**\n * Injects theme tab into existing tabs field\n */\nconst injectThemeTab = (\n fields: Field[] | undefined,\n themeTab: ThemeTab,\n enableLogging: boolean,\n): Field[] => {\n // First, remove any legacy theme field (group-based)\n const sanitizedFields = removeExistingThemeField(fields ?? [])\n\n // Find the tabs field\n const tabsField = findTabsField(sanitizedFields)\n\n if (!tabsField || !tabsField.tabs) {\n if (enableLogging) {\n console.warn(\n '🎨 Theme Management Plugin: No tabs field found. Creating a new tabs structure.',\n )\n }\n\n // If no tabs exist, create a basic tabs structure with just the theme tab\n const newTabsField: TabsField = {\n type: 'tabs',\n tabs: [themeTab],\n }\n\n return [...sanitizedFields, newTabsField]\n }\n\n // Remove existing theme tab if present\n const sanitizedTabs = removeExistingThemeTab(tabsField.tabs)\n\n // Add theme tab to the end\n const updatedTabs = [...sanitizedTabs, themeTab]\n\n if (enableLogging) {\n console.log('🎨 Theme Management Plugin: injecting Appearance Settings tab')\n }\n\n // Update the tabs field\n const updatedTabsField: TabsField = {\n ...tabsField,\n tabs: updatedTabs,\n }\n\n // Replace the old tabs field with the updated one\n return sanitizedFields.map((field) => (field.type === 'tabs' ? updatedTabsField : field))\n}\n\nconst ensureCollectionsArray = (collections: Config['collections']): CollectionConfig[] =>\n Array.isArray(collections) ? collections : []\n\nconst ensureEndpointsArray = (endpoints: Config['endpoints']): NonNullable<Config['endpoints']> =>\n Array.isArray(endpoints) ? endpoints : []\n\ntype NormalizedLivePreviewOptions = {\n enabled: boolean\n injectRoute: boolean\n routePath: string\n pageCollection: string\n pageSlug: string\n fallbackToFirstPage: boolean\n tenantField: string\n tenantQueryParam: string\n breakpoints?: ThemeManagementLivePreviewOptions['breakpoints']\n url?: ThemeManagementLivePreviewOptions['url']\n}\n\ntype NormalizedCacheRevalidationOptions = {\n enabled: boolean\n injectRoute: boolean\n routePath: string\n secret?: string\n tags: string[]\n paths: string[]\n}\n\ntype MinimalPayloadRequest = ThemeManagementLivePreviewUrlArgs['req']\n\nconst normalizeLivePreviewOptions = (\n livePreview: ThemeManagementPluginOptions['livePreview'],\n): NormalizedLivePreviewOptions => {\n if (livePreview === false) {\n return {\n enabled: false,\n injectRoute: false,\n routePath: '/theme/preview',\n pageCollection: 'pages',\n pageSlug: 'home',\n fallbackToFirstPage: true,\n tenantField: 'tenant',\n tenantQueryParam: 'tenant',\n breakpoints: undefined,\n }\n }\n\n const raw = typeof livePreview === 'object' && livePreview ? livePreview : {}\n\n return {\n enabled: raw.enabled ?? true,\n injectRoute: raw.injectRoute ?? false,\n routePath: normalizeRoutePath(raw.routePath),\n pageCollection: raw.pageCollection ?? 'pages',\n pageSlug: raw.pageSlug ?? 'home',\n fallbackToFirstPage: raw.fallbackToFirstPage ?? true,\n tenantField: raw.tenantField ?? 'tenant',\n tenantQueryParam: raw.tenantQueryParam ?? 'tenant',\n breakpoints: raw.breakpoints,\n url: raw.url,\n }\n}\n\nconst dedupeStrings = (values: (string | undefined)[]): string[] => [\n ...new Set(\n values.filter((value): value is string => typeof value === 'string' && value.trim().length > 0),\n ),\n]\n\nconst normalizeRoutePath = (path: string | undefined): string => {\n if (!path || !path.trim()) {\n return '/theme/revalidate'\n }\n\n return path.startsWith('/') ? path : `/${path}`\n}\n\nconst normalizeCacheRevalidationOptions = (args: {\n cacheRevalidation: ThemeManagementPluginOptions['cacheRevalidation']\n standaloneCollectionSlug: string\n useStandaloneCollection: boolean\n}): NormalizedCacheRevalidationOptions => {\n const { cacheRevalidation, standaloneCollectionSlug, useStandaloneCollection } = args\n\n if (cacheRevalidation === false) {\n return {\n enabled: false,\n injectRoute: false,\n routePath: '/theme/revalidate',\n tags: [],\n paths: [],\n }\n }\n\n const raw = typeof cacheRevalidation === 'object' && cacheRevalidation ? cacheRevalidation : {}\n const defaultTag = `global_${standaloneCollectionSlug}`\n\n return {\n enabled: raw.enabled ?? useStandaloneCollection,\n injectRoute: raw.injectRoute ?? true,\n routePath: normalizeRoutePath(raw.routePath),\n secret: raw.secret,\n tags: dedupeStrings([defaultTag, ...(raw.tags ?? [])]),\n paths: dedupeStrings(raw.paths ?? []),\n }\n}\n\nconst asRecord = (value: unknown): Record<string, unknown> | undefined => {\n if (value && typeof value === 'object') {\n return value as Record<string, unknown>\n }\n return undefined\n}\n\nconst pickString = (value: unknown): string | undefined => {\n if (typeof value === 'string' && value.trim()) return value\n return undefined\n}\n\nconst extractTenantValue = (value: unknown): string | undefined => {\n if (!value) return undefined\n if (typeof value === 'string') return pickString(value)\n\n const tenantRecord = asRecord(value)\n if (!tenantRecord) return undefined\n\n return (\n pickString(tenantRecord.id) ??\n pickString(tenantRecord.slug) ??\n pickString(tenantRecord.value) ??\n pickString(tenantRecord.tenant)\n )\n}\n\nconst resolveTenantSlug = (\n req: MinimalPayloadRequest,\n tenantField: string,\n data?: Record<string, unknown>,\n): string | undefined => {\n const fromData = extractTenantValue(data?.[tenantField])\n if (fromData) return fromData\n\n const query = req.query\n if (query && typeof URLSearchParams !== 'undefined' && query instanceof URLSearchParams) {\n return (\n pickString(query.get('tenant')) ??\n pickString(query.get('tenantSlug')) ??\n pickString(query.get('tenantId'))\n )\n }\n\n const queryRecord = asRecord(query)\n const fromQuery =\n extractTenantValue(queryRecord?.tenant) ??\n extractTenantValue(queryRecord?.tenantSlug) ??\n extractTenantValue(queryRecord?.tenantId)\n if (fromQuery) return fromQuery\n\n const userRecord = asRecord(req.user)\n const fromUser =\n extractTenantValue(userRecord?.[tenantField]) ??\n extractTenantValue(userRecord?.tenant) ??\n extractTenantValue(userRecord?.tenantSlug)\n if (fromUser) return fromUser\n\n const headers = req.headers\n if (headers && typeof Headers !== 'undefined' && headers instanceof Headers) {\n return (\n pickString(headers.get('x-tenant-id')) ??\n pickString(headers.get('x-tenant')) ??\n pickString(headers.get('payload-tenant'))\n )\n }\n\n const headerRecord = asRecord(headers)\n return (\n extractTenantValue(headerRecord?.['x-tenant-id']) ??\n extractTenantValue(headerRecord?.['x-tenant']) ??\n extractTenantValue(headerRecord?.['payload-tenant'])\n )\n}\n\nconst buildDefaultPreviewPath = (\n pageSlug: string,\n tenantSlug: string | undefined,\n tenantQueryParam: string,\n): string => {\n const normalizedSlug = pageSlug === 'home' ? '' : pageSlug\n const basePath = normalizedSlug ? `/${normalizedSlug}` : '/'\n\n if (!tenantSlug) {\n return basePath\n }\n\n const separator = basePath.includes('?') ? '&' : '?'\n return `${basePath}${separator}${tenantQueryParam}=${encodeURIComponent(tenantSlug)}`\n}\n\nconst resolveLivePreviewUrl = async (args: {\n req: MinimalPayloadRequest\n data?: Record<string, unknown>\n livePreview: NormalizedLivePreviewOptions\n enableLogging: boolean\n}): Promise<string> => {\n const { req, data, livePreview, enableLogging } = args\n\n const tenantSlug = resolveTenantSlug(req, livePreview.tenantField, data)\n\n const tenantWhere = tenantSlug\n ? {\n [livePreview.tenantField]: {\n equals: tenantSlug,\n },\n }\n : undefined\n\n const homeWhere = {\n and: [\n {\n slug: {\n equals: livePreview.pageSlug,\n },\n },\n ...(tenantWhere ? [tenantWhere] : []),\n ],\n }\n\n try {\n const preferredPageResponse = await req.payload.find({\n collection: livePreview.pageCollection,\n where: homeWhere,\n depth: 0,\n draft: true,\n limit: 1,\n overrideAccess: true,\n pagination: false,\n })\n\n let page = preferredPageResponse?.docs?.[0]\n\n if (!page && livePreview.fallbackToFirstPage) {\n const fallbackResponse = await req.payload.find({\n collection: livePreview.pageCollection,\n where: tenantWhere,\n depth: 0,\n draft: true,\n limit: 1,\n overrideAccess: true,\n pagination: false,\n })\n\n page = fallbackResponse?.docs?.[0]\n }\n\n const pageRecord = asRecord(page)\n const resolvedPageSlug = pickString(pageRecord?.slug) ?? livePreview.pageSlug\n\n if (livePreview.url) {\n return await livePreview.url({\n page: pageRecord,\n pageSlug: resolvedPageSlug,\n tenantSlug,\n req,\n })\n }\n\n return buildDefaultPreviewPath(resolvedPageSlug, tenantSlug, livePreview.tenantQueryParam)\n } catch (error) {\n if (enableLogging) {\n req.payload.logger?.warn?.(\n '🎨 Theme Management Plugin: live preview URL fallback used',\n error,\n )\n }\n\n return buildDefaultPreviewPath(livePreview.pageSlug, tenantSlug, livePreview.tenantQueryParam)\n }\n}\n\nconst createPreviewAdminConfig = (\n normalizedLivePreview: NormalizedLivePreviewOptions,\n enableLogging: boolean,\n) => {\n if (!normalizedLivePreview.enabled) {\n return {}\n }\n\n return {\n livePreview: {\n breakpoints: normalizedLivePreview.breakpoints,\n url: ({ data, req }: { data?: unknown; req: unknown }) =>\n resolveLivePreviewUrl({\n req: req as MinimalPayloadRequest,\n data: asRecord(data),\n livePreview: normalizedLivePreview,\n enableLogging,\n }),\n },\n preview: (data: Record<string, unknown>, options: { req?: unknown }) => {\n const req = options?.req\n if (!req) return null\n\n return resolveLivePreviewUrl({\n req: req as MinimalPayloadRequest,\n data,\n livePreview: normalizedLivePreview,\n enableLogging,\n })\n },\n }\n}\n\nconst readSecretFromRequest = async (req: unknown): Promise<string | undefined> => {\n const requestRecord = asRecord(req)\n const headersValue = requestRecord?.headers\n\n if (headersValue && typeof Headers !== 'undefined' && headersValue instanceof Headers) {\n return (\n pickString(headersValue.get('x-theme-revalidate-secret')) ??\n pickString(headersValue.get('x-revalidate-secret'))\n )\n }\n\n const headerRecord = asRecord(headersValue)\n const fromHeaders =\n pickString(headerRecord?.['x-theme-revalidate-secret']) ??\n pickString(headerRecord?.['x-revalidate-secret'])\n if (fromHeaders) {\n return fromHeaders\n }\n\n const requestWithJson = req as { json?: () => Promise<unknown> }\n const body =\n typeof requestWithJson?.json === 'function' ? await requestWithJson.json() : undefined\n const bodyRecord = asRecord(body)\n const fromBody = pickString(bodyRecord?.secret)\n if (fromBody) {\n return fromBody\n }\n\n const queryRecord = asRecord(requestRecord?.query)\n return pickString(queryRecord?.secret)\n}\n\nconst executeThemeRevalidation = async (options: {\n tags: string[]\n paths: string[]\n enableLogging: boolean\n logger?: { info?: (...args: any[]) => void; error?: (...args: any[]) => void }\n}): Promise<{ tags: string[]; paths: string[] }> => {\n const { tags, paths, enableLogging, logger } = options\n\n try {\n const { revalidatePath, revalidateTag } = await import('next/cache')\n\n tags.forEach((tag) => revalidateTag(tag))\n paths.forEach((path) => revalidatePath(path))\n\n if (enableLogging) {\n logger?.info?.(\n `🎨 Theme Management Plugin: revalidated cache tags=[${tags.join(', ')}] paths=[${paths.join(', ')}]`,\n )\n }\n } catch (error) {\n if (enableLogging) {\n logger?.error?.('🎨 Theme Management Plugin: cache invalidation failed:', error)\n }\n throw error\n }\n\n return { tags, paths }\n}\n\nconst readQueryStringFromRequest = (req: unknown, paramName: string): string | undefined => {\n const reqRecord = asRecord(req)\n\n // Try URLSearchParams from native fetch/Node.js\n const queryValue = reqRecord?.query\n if (\n queryValue &&\n typeof URLSearchParams !== 'undefined' &&\n queryValue instanceof URLSearchParams\n ) {\n return pickString(queryValue.get(paramName))\n }\n\n // Try object form (common in Payload)\n const queryRecord = asRecord(queryValue)\n if (queryRecord) {\n const rawValue = queryRecord[paramName]\n if (Array.isArray(rawValue)) {\n return pickString(rawValue[0])\n }\n return pickString(rawValue)\n }\n\n // Try manual URL parsing as fallback\n const urlValue = pickString(reqRecord?.url) ?? pickString(reqRecord?.originalUrl)\n if (urlValue) {\n try {\n const url = new URL(urlValue, 'http://localhost')\n return pickString(url.searchParams.get(paramName))\n } catch {\n // Ignore parse errors\n }\n }\n\n return undefined\n}\n\nconst createLivePreviewEndpoint = (options: {\n livePreview: NormalizedLivePreviewOptions\n enableLogging: boolean\n}) => {\n const { livePreview, enableLogging } = options\n\n if (!livePreview.enabled || !livePreview.injectRoute) {\n return null\n }\n\n return {\n path: livePreview.routePath,\n method: 'get',\n handler: async (req: unknown) => {\n const previewSecret = process.env.PREVIEW_SECRET ?? process.env.PAYLOAD_PREVIEW_SECRET\n\n if (previewSecret) {\n const providedSecret =\n readQueryStringFromRequest(req, 'previewSecret') ??\n readQueryStringFromRequest(req, 'preview')\n if (providedSecret !== previewSecret) {\n return jsonResponse({ error: 'Unauthorized' }, 401)\n }\n }\n\n const pageSlug = readQueryStringFromRequest(req, 'pageSlug') ?? livePreview.pageSlug\n const tenantSlug = readQueryStringFromRequest(req, 'tenant')\n\n // Redirect to the actual client page (standard Payload live preview behavior)\n const destination = buildDefaultPreviewPath(\n pageSlug,\n tenantSlug,\n livePreview.tenantQueryParam,\n )\n\n if (enableLogging) {\n console.log('🎨 Theme Management Plugin: live preview redirect', destination)\n }\n\n return {\n status: 307,\n headers: {\n Location: destination,\n },\n }\n },\n }\n}\n\nconst createCacheRevalidationEndpoint = (options: {\n cacheRevalidation: NormalizedCacheRevalidationOptions\n enableLogging: boolean\n}) => {\n const { cacheRevalidation, enableLogging } = options\n\n if (!cacheRevalidation.enabled || !cacheRevalidation.injectRoute) {\n return null\n }\n\n return {\n path: cacheRevalidation.routePath,\n method: 'post',\n handler: async (req: unknown) => {\n const reqRecord = asRecord(req)\n const payload = asRecord(reqRecord?.payload)\n const logger = payload?.logger as\n | { info?: (...args: any[]) => void; error?: (...args: any[]) => void }\n | undefined\n\n if (cacheRevalidation.secret) {\n const providedSecret = await readSecretFromRequest(req)\n if (providedSecret !== cacheRevalidation.secret) {\n return jsonResponse({ error: 'Unauthorized' }, 401)\n }\n }\n\n try {\n const result = await executeThemeRevalidation({\n tags: cacheRevalidation.tags,\n paths: cacheRevalidation.paths,\n enableLogging,\n logger,\n })\n\n return jsonResponse({ ok: true, revalidated: result })\n } catch {\n return jsonResponse({ ok: false, error: 'Revalidation failed' }, 500)\n }\n },\n }\n}\n\nconst mergeEndpoint = (\n endpoints: NonNullable<Config['endpoints']>,\n endpoint: unknown,\n): NonNullable<Config['endpoints']> => {\n if (!endpoint) {\n return endpoints\n }\n\n const record = endpoint as unknown as { path?: string; method?: string }\n\n const withoutExisting = endpoints.filter((candidate) => {\n const candidateRecord = candidate as unknown as { path?: string; method?: string }\n return !(\n candidateRecord?.path === record?.path &&\n typeof candidateRecord.method === 'string' &&\n typeof record.method === 'string' &&\n candidateRecord.method.toLowerCase() === record.method.toLowerCase()\n )\n })\n\n return [...withoutExisting, endpoint as unknown as NonNullable<Config['endpoints']>[number]]\n}\n\nconst jsonResponse = (body: Record<string, unknown>, status = 200): unknown => {\n if (typeof Response !== 'undefined' && typeof Response.json === 'function') {\n return Response.json(body, { status })\n }\n\n return {\n status,\n json: async () => body,\n }\n}\n\nexport const themeManagementPlugin = (options: ThemeManagementPluginOptions = {}): Plugin => {\n return (config: Config): Config => {\n const {\n enabled = true,\n targetCollection = 'site-settings',\n useStandaloneCollection = false,\n standaloneCollectionSlug = 'appearance-settings',\n // Allow either string or localized object; default comes from plugin translations\n standaloneCollectionLabel = getTranslations().standaloneCollectionLabel,\n themePresets = allThemePresets,\n defaultTheme = 'cool',\n includeColorModeToggle = true,\n includeCustomCSS = true,\n includeBrandIdentity = false,\n enableAdvancedFeatures = true,\n enableLogging = false,\n livePreview = true,\n cacheRevalidation,\n } = options\n\n const normalizedLivePreview = normalizeLivePreviewOptions(livePreview)\n const normalizedCacheRevalidation = normalizeCacheRevalidationOptions({\n cacheRevalidation,\n standaloneCollectionSlug,\n useStandaloneCollection,\n })\n\n if (!enabled) {\n if (enableLogging) {\n console.log('🎨 Theme Management Plugin: disabled via options, skipping.')\n }\n return config\n }\n\n const themeTab = createThemeConfigurationField({\n themePresets,\n defaultTheme,\n includeColorModeToggle,\n includeCustomCSS,\n includeBrandIdentity: includeBrandIdentity ?? false,\n enableAdvancedFeatures,\n useThemePreviewField: !normalizedLivePreview.enabled,\n })\n\n // If using standalone collection, create a new global\n if (useStandaloneCollection) {\n if (enableLogging) {\n console.log(\n `🎨 Theme Management Plugin: creating standalone global \"${standaloneCollectionSlug}\"`,\n )\n }\n\n // Extract the fields from the tab directly (no wrapping in group)\n const tabFields = (themeTab.fields ?? []) as Field[]\n\n /**\n * Hook to auto-populate lightMode and darkMode colors when theme changes\n */\n type BeforeChangeArgs = {\n data?: {\n themeConfiguration?: {\n theme?: string\n lightMode?: Record<string, unknown>\n darkMode?: Record<string, unknown>\n }\n }\n }\n\n const beforeChangeHook = async (args: BeforeChangeArgs) => {\n const { data } = args\n\n // If theme is being changed, auto-populate color modes\n if (data?.themeConfiguration?.theme) {\n const themeName = data.themeConfiguration.theme\n const selectedPreset = themePresets.find((p) => p.name === themeName)\n\n if (selectedPreset) {\n // Initialize light and dark mode colors from preset if not already set\n if (!data.themeConfiguration.lightMode) {\n data.themeConfiguration.lightMode = {}\n }\n if (!data.themeConfiguration.darkMode) {\n data.themeConfiguration.darkMode = {}\n }\n\n // Only populate if not manually edited (first time or empty)\n const isLightModeEmpty = !data.themeConfiguration.lightMode?.background\n const isDarkModeEmpty = !data.themeConfiguration.darkMode?.background\n\n if (isLightModeEmpty && selectedPreset.lightMode) {\n data.themeConfiguration.lightMode = { ...selectedPreset.lightMode }\n }\n\n if (isDarkModeEmpty && selectedPreset.darkMode) {\n data.themeConfiguration.darkMode = { ...selectedPreset.darkMode }\n }\n }\n }\n\n return data\n }\n\n const standaloneGlobal: GlobalConfig = {\n slug: standaloneCollectionSlug,\n label: standaloneCollectionLabel,\n admin: {\n group: 'Settings',\n ...createPreviewAdminConfig(normalizedLivePreview, enableLogging),\n },\n // Provide a broad access object but cast to GlobalConfig['access'] to satisfy types\n access: ((): GlobalConfig['access'] => {\n const accessObj = {\n read: () => true,\n create: ({ req }: { req?: { user?: unknown } }) => !!req?.user,\n update: ({ req }: { req?: { user?: unknown } }) => !!req?.user,\n delete: ({ req }: { req?: { user?: unknown } }) => !!req?.user,\n } as unknown as GlobalConfig['access']\n return accessObj\n })(),\n fields: tabFields,\n hooks: {\n beforeChange: [beforeChangeHook],\n afterChange: [\n async ({ doc, req }) => {\n // Invalidate cache after appearance settings change\n if (!req?.context?.disableRevalidate && normalizedCacheRevalidation.enabled) {\n try {\n await executeThemeRevalidation({\n tags: normalizedCacheRevalidation.tags,\n paths: normalizedCacheRevalidation.paths,\n enableLogging,\n logger: req?.payload?.logger,\n })\n } catch {\n // no-op: logging is handled in executeThemeRevalidation\n }\n }\n return doc\n },\n ],\n },\n }\n\n const globals = Array.isArray(config.globals) ? config.globals : []\n\n // Check if global already exists\n const existingIndex = globals.findIndex((g) => g.slug === standaloneCollectionSlug)\n\n if (existingIndex !== -1) {\n if (enableLogging) {\n console.warn(\n `🎨 Theme Management Plugin: global \"${standaloneCollectionSlug}\" already exists, skipping creation.`,\n )\n }\n return config\n }\n\n const currentEndpoints = ensureEndpointsArray(config.endpoints)\n const livePreviewEndpoint = createLivePreviewEndpoint({\n livePreview: normalizedLivePreview,\n enableLogging,\n })\n let endpoints = mergeEndpoint(currentEndpoints, livePreviewEndpoint)\n const cacheEndpoint = createCacheRevalidationEndpoint({\n cacheRevalidation: normalizedCacheRevalidation,\n enableLogging,\n })\n endpoints = mergeEndpoint(endpoints, cacheEndpoint)\n\n return {\n ...config,\n endpoints,\n globals: [...globals, standaloneGlobal],\n }\n }\n\n // Otherwise, add as tab to existing collection\n let collectionTouched = false\n\n const collections = ensureCollectionsArray(config.collections).map((collection) => {\n if (collection.slug !== targetCollection) {\n return collection\n }\n\n collectionTouched = true\n\n if (enableLogging) {\n console.log(`🎨 Theme Management Plugin: enhancing collection \"${collection.slug}\"`)\n }\n\n const existingFields = Array.isArray(collection.fields) ? collection.fields : []\n\n const fields = injectThemeTab(existingFields, themeTab, enableLogging)\n\n const admin = {\n ...collection.admin,\n ...createPreviewAdminConfig(normalizedLivePreview, enableLogging),\n }\n\n return {\n ...collection,\n fields,\n admin,\n }\n })\n\n if (!collectionTouched) {\n if (enableLogging) {\n console.warn(\n `🎨 Theme Management Plugin: collection \"${targetCollection}\" was not found, leaving config untouched.`,\n )\n }\n return config\n }\n\n const currentEndpoints = ensureEndpointsArray(config.endpoints)\n const livePreviewEndpoint = createLivePreviewEndpoint({\n livePreview: normalizedLivePreview,\n enableLogging,\n })\n let endpoints = mergeEndpoint(currentEndpoints, livePreviewEndpoint)\n const cacheEndpoint = createCacheRevalidationEndpoint({\n cacheRevalidation: normalizedCacheRevalidation,\n enableLogging,\n })\n endpoints = mergeEndpoint(endpoints, cacheEndpoint)\n\n return {\n ...config,\n endpoints,\n collections,\n }\n }\n}\n\ntype FetchOptionsInput = string | FetchThemeConfigurationOptions\n\nexport const fetchThemeConfiguration = async (\n options?: FetchOptionsInput,\n): Promise<SiteThemeConfiguration | null> => {\n const normalizedOptions = typeof options === 'string' ? { tenantSlug: options } : (options ?? {})\n\n const {\n tenantSlug,\n collectionSlug = 'site-settings', // Can be overridden to 'appearance-settings' if using standalone\n depth,\n locale,\n draft,\n queryParams = {},\n useGlobal = false, // Set to true if using standalone global instead of collection\n } = normalizedOptions\n\n try {\n if (useGlobal) {\n // Fetch from global endpoint\n const params = new URLSearchParams()\n\n if (typeof depth === 'number') params.set('depth', String(depth))\n // For globals, keep tenant param for backwards compatibility, and also add where[...] filter\n if (tenantSlug) {\n params.set('tenant', tenantSlug)\n params.set('where[tenant][equals]', String(tenantSlug))\n }\n\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value === undefined) return\n params.set(key, String(value))\n })\n\n const queryString = params.toString()\n const url = `/api/globals/${collectionSlug}${queryString ? `?${queryString}` : ''}`\n\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch theme global (status ${response.status})`)\n }\n\n const data = (await response.json()) as {\n themeConfiguration?: SiteThemeConfiguration\n }\n\n return data?.themeConfiguration ?? null\n } else {\n // Fetch from collection endpoint (legacy/default behavior)\n const params = new URLSearchParams({ limit: '1' })\n\n if (typeof depth === 'number') params.set('depth', String(depth))\n // For collections, use a where[tenant][equals] filter so Payload's find endpoint applies tenant scoping\n if (tenantSlug) params.set('where[tenant][equals]', String(tenantSlug))\n if (locale) params.set('locale', locale)\n if (draft) params.set('draft', 'true')\n\n Object.entries(queryParams).forEach(([key, value]) => {\n if (value === undefined) return\n params.set(key, String(value))\n })\n\n const url = `/api/${collectionSlug}?${params.toString()}`\n\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to fetch theme configuration (status ${response.status})`)\n }\n\n const data = (await response.json()) as {\n docs?: Array<{ themeConfiguration?: SiteThemeConfiguration }>\n }\n\n const doc = data.docs?.[0]\n\n return doc?.themeConfiguration ?? null\n }\n } catch (error) {\n console.warn('Failed to fetch theme configuration:', error)\n return null\n }\n}\n\nexport const getThemePreset = (themeName: string): ThemePreset | null => {\n return allThemePresets.find((preset) => preset.name === themeName) || null\n}\n\nexport const getAvailableThemePresets = (): ThemePreset[] => {\n return allThemePresets\n}\n\nexport { defaultThemePresets, allThemePresets } from './presets.js'\nexport type { ThemePreset, ThemeTypographyPreset } from './presets.js'\nexport type { ThemeTab } from './fields/themeConfigurationField.js'\nexport {\n extendedThemePresets,\n allExtendedThemePresets,\n extendedThemeToCSSVariables,\n} from './extended-presets.js'\nexport type { ExtendedThemePreset, ShadcnColorTokens } from './extended-presets.js'\nexport {\n applyExtendedTheme,\n generateExtendedThemeCSS,\n resetExtendedTheme,\n getExtendedThemeTokens,\n createUseExtendedTheme,\n getTailwindVarReferences,\n} from './utils/extendedThemeHelpers.js'\nexport type {\n ThemeManagementPluginOptions,\n ThemeManagementCacheRevalidationOptions,\n FetchThemeConfigurationOptions,\n ThemeManagementLivePreviewOptions,\n ThemeManagementLivePreviewUrlArgs,\n} from './types.js'\nexport {\n DEFAULT_THEME_CONFIGURATION,\n resolveThemeConfiguration,\n} from './utils/resolveThemeConfiguration.js'\nexport type { ResolvedThemeConfiguration } from './utils/resolveThemeConfiguration.js'\nexport { generateThemeColorsCss, hexToHsl } from './utils/themeColors.js'\nexport { generateThemeCSS, getThemeStyles } from './utils/themeUtils.js'\nexport { getThemeHtmlAttributes } from './utils/themeHtmlAttributes.js'\n\n// Dynamic theme CSS generation\nexport {\n generateThemeCSS as generatePresetCSS,\n generateAllThemesCSS,\n} from './utils/generateThemeCSS.js'\nexport { getThemeDynamicCSS, getAllDynamicThemesCSS } from './utils/themeCSS.js'\n\nexport type { Mode, ThemeDefaults } from './providers/Theme/types.js'\nexport { ThemeProvider } from './providers/Theme/index.js'\n\n// Font loading utilities for Next.js integration\nexport {\n getFontLoaderCode,\n getThemeFontFamilies,\n ThemeFontProvider,\n useThemeFonts,\n FONT_IMPORT_MAP,\n} from './providers/font-loader.js'\n\n// Note: Do NOT re-export client components from the root entry to avoid\n// server-side evaluation during `payload generate:importmap`.\n// If needed, import directly from subpath: `@kilivi/payloadcms-theme-management/fields/ThemeLivePreview`\n\nexport const ThemeManagementPlugin = themeManagementPlugin\n/** @deprecated use {@link themeManagementPlugin} */\nexport const themeConfigurationPlugin = themeManagementPlugin\n\n// Export plugin translations for consumers to merge into their payload translations\nexport {\n translations,\n getTranslations,\n registerTranslations,\n availableLanguages,\n} from './translations.js'\n\nexport default themeManagementPlugin\n"],"names":["createThemeConfigurationField","allThemePresets","getTranslations","translations","THEME_FIELD_NAME","removeExistingThemeField","fields","filter","field","candidate","name","findTabsField","type","removeExistingThemeTab","tabs","knownLabels","Object","values","map","t","tabLabel","tab","labelValues","label","matchesKnown","some","v","includes","injectThemeTab","themeTab","enableLogging","sanitizedFields","tabsField","console","warn","newTabsField","sanitizedTabs","updatedTabs","log","updatedTabsField","ensureCollectionsArray","collections","Array","isArray","ensureEndpointsArray","endpoints","normalizeLivePreviewOptions","livePreview","enabled","injectRoute","routePath","pageCollection","pageSlug","fallbackToFirstPage","tenantField","tenantQueryParam","breakpoints","undefined","raw","normalizeRoutePath","url","dedupeStrings","Set","value","trim","length","path","startsWith","normalizeCacheRevalidationOptions","args","cacheRevalidation","standaloneCollectionSlug","useStandaloneCollection","tags","paths","defaultTag","secret","asRecord","pickString","extractTenantValue","tenantRecord","id","slug","tenant","resolveTenantSlug","req","data","fromData","query","URLSearchParams","get","queryRecord","fromQuery","tenantSlug","tenantId","userRecord","user","fromUser","headers","Headers","headerRecord","buildDefaultPreviewPath","normalizedSlug","basePath","separator","encodeURIComponent","resolveLivePreviewUrl","tenantWhere","equals","homeWhere","and","preferredPageResponse","payload","find","collection","where","depth","draft","limit","overrideAccess","pagination","page","docs","fallbackResponse","pageRecord","resolvedPageSlug","error","logger","createPreviewAdminConfig","normalizedLivePreview","preview","options","readSecretFromRequest","requestRecord","headersValue","fromHeaders","requestWithJson","body","json","bodyRecord","fromBody","executeThemeRevalidation","revalidatePath","revalidateTag","forEach","tag","info","join","readQueryStringFromRequest","paramName","reqRecord","queryValue","rawValue","urlValue","originalUrl","URL","searchParams","createLivePreviewEndpoint","method","handler","previewSecret","process","env","PREVIEW_SECRET","PAYLOAD_PREVIEW_SECRET","providedSecret","jsonResponse","destination","status","Location","createCacheRevalidationEndpoint","result","ok","revalidated","mergeEndpoint","endpoint","record","withoutExisting","candidateRecord","toLowerCase","Response","themeManagementPlugin","config","targetCollection","standaloneCollectionLabel","themePresets","defaultTheme","includeColorModeToggle","includeCustomCSS","includeBrandIdentity","enableAdvancedFeatures","normalizedCacheRevalidation","useThemePreviewField","tabFields","beforeChangeHook","themeConfiguration","theme","themeName","selectedPreset","p","lightMode","darkMode","isLightModeEmpty","background","isDarkModeEmpty","standaloneGlobal","admin","group","access","accessObj","read","create","update","delete","hooks","beforeChange","afterChange","doc","context","disableRevalidate","globals","existingIndex","findIndex","g","currentEndpoints","livePreviewEndpoint","cacheEndpoint","collectionTouched","existingFields","fetchThemeConfiguration","normalizedOptions","collectionSlug","locale","queryParams","useGlobal","params","set","String","entries","key","queryString","toString","response","fetch","Error","getThemePreset","preset","getAvailableThemePresets","defaultThemePresets","extendedThemePresets","allExtendedThemePresets","extendedThemeToCSSVariables","applyExtendedTheme","generateExtendedThemeCSS","resetExtendedTheme","getExtendedThemeTokens","createUseExtendedTheme","getTailwindVarReferences","DEFAULT_THEME_CONFIGURATION","resolveThemeConfiguration","generateThemeColorsCss","hexToHsl","generateThemeCSS","getThemeStyles","getThemeHtmlAttributes","generatePresetCSS","generateAllThemesCSS","getThemeDynamicCSS","getAllDynamicThemesCSS","ThemeProvider","getFontLoaderCode","getThemeFontFamilies","ThemeFontProvider","useThemeFonts","FONT_IMPORT_MAP","ThemeManagementPlugin","themeConfigurationPlugin","registerTranslations","availableLanguages"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -24,6 +24,10 @@ export interface ThemeManagementLivePreviewUrlArgs {
|
|
|
24
24
|
export interface ThemeManagementLivePreviewOptions {
|
|
25
25
|
/** Enable Payload admin live preview for the target config (default: true) */
|
|
26
26
|
enabled?: boolean;
|
|
27
|
+
/** Inject a Payload endpoint for live preview (enables `/api/theme/preview`) (default: false) */
|
|
28
|
+
injectRoute?: boolean;
|
|
29
|
+
/** Endpoint path under Payload API (default: '/theme/preview') */
|
|
30
|
+
routePath?: string;
|
|
27
31
|
/** Collection slug containing preview pages (default: 'pages') */
|
|
28
32
|
pageCollection?: string;
|
|
29
33
|
/** Preferred page slug for preview (default: 'home') */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { ThemePreset } from './presets.js'\n\nexport interface ThemeManagementLivePreviewUrlArgs {\n /** Resolved preview page document (if found) */\n page?: Record<string, unknown>\n /** Resolved preview page slug */\n pageSlug: string\n /** Inferred tenant identifier (if available) */\n tenantSlug?: string\n /** Current Payload request */\n req: {\n payload: {\n find: (args: Record<string, unknown>) => Promise<{ docs?: Array<Record<string, unknown>> }>\n logger?: {\n warn?: (...args: unknown[]) => void\n }\n }\n query?: unknown\n headers?: unknown\n user?: unknown\n }\n}\n\nexport interface ThemeManagementLivePreviewOptions {\n /** Enable Payload admin live preview for the target config (default: true) */\n enabled?: boolean\n /** Collection slug containing preview pages (default: 'pages') */\n pageCollection?: string\n /** Preferred page slug for preview (default: 'home') */\n pageSlug?: string\n /** Fallback to first page if preferred slug does not exist (default: true) */\n fallbackToFirstPage?: boolean\n /** Tenant field name used for filtering in multi-tenant setups (default: 'tenant') */\n tenantField?: string\n /** Query param name appended to default URL when tenant is resolved (default: 'tenant') */\n tenantQueryParam?: string\n /**\n * Device breakpoints shown in Payload's Live Preview toolbar (iframe size presets).\n * Use this to make preview sizing more practical for your editors.\n */\n breakpoints?: Array<{\n name: string\n label: string\n width: number | string\n height: number | string\n }>\n /**\n * Custom URL resolver for Payload live preview.\n * Defaults to `/${slug}` (or `/` for `home`) with optional tenant query param.\n */\n url?: (args: ThemeManagementLivePreviewUrlArgs) => string | Promise<string>\n}\n\nexport interface ThemeManagementCacheRevalidationOptions {\n /** Enable cache revalidation support (default: true for standalone mode, false for tab mode) */\n enabled?: boolean\n /** Inject a Payload endpoint for manual/external revalidation triggers (default: true) */\n injectRoute?: boolean\n /** Endpoint path under Payload API (default: '/theme/revalidate') */\n routePath?: string\n /** Optional shared secret checked against header/body/query before revalidation */\n secret?: string\n /** Additional tags to revalidate together with the default global tag */\n tags?: string[]\n /** Optional paths to revalidate together with tags */\n paths?: string[]\n}\n\nexport interface ThemeManagementPluginOptions {\n /** Whether the plugin should register itself */\n enabled?: boolean\n /** Collection slug that stores site-level settings (default: `site-settings`) */\n targetCollection?: string\n /** Create a standalone collection instead of adding as a tab (default: false) */\n useStandaloneCollection?: boolean\n /** Name of the standalone collection (default: 'appearance-settings') */\n standaloneCollectionSlug?: string\n /** Label for the standalone collection (default: 'Appearance Settings') */\n standaloneCollectionLabel?: string | Record<string, string>\n /** Theme presets available to editors */\n themePresets?: ThemePreset[]\n /** Default preset name when no value is stored */\n defaultTheme?: string\n /** Allow editors to toggle between light / dark / auto modes */\n includeColorModeToggle?: boolean\n /** Expose custom CSS editor */\n includeCustomCSS?: boolean\n /** Reserved for future use, keeps API parity */\n includeBrandIdentity?: boolean\n /** Enable advanced controls such as animation level */\n enableAdvancedFeatures?: boolean\n /** Log helpful messages during config mutation */\n enableLogging?: boolean\n /** Configure Payload admin live preview URL generation */\n livePreview?: boolean | ThemeManagementLivePreviewOptions\n /** Configure cache revalidation route and tags for Next.js `unstable_cache` usage */\n cacheRevalidation?: boolean | ThemeManagementCacheRevalidationOptions\n}\n\nexport interface FetchThemeConfigurationOptions {\n /** Optional tenant identifier if your project is multi-tenant */\n tenantSlug?: string\n /** Collection/Global slug override (default: `site-settings`) */\n collectionSlug?: string\n /** Depth parameter passed to Payload REST API */\n depth?: number\n /** Locale parameter passed to Payload REST API */\n locale?: string\n /** Include draft documents */\n draft?: boolean\n /** Extra query parameters to append to the request */\n queryParams?: Record<string, string | number | boolean>\n /** Set to true if using standalone global instead of collection (default: false) */\n useGlobal?: boolean\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { ThemePreset } from './presets.js'\n\nexport interface ThemeManagementLivePreviewUrlArgs {\n /** Resolved preview page document (if found) */\n page?: Record<string, unknown>\n /** Resolved preview page slug */\n pageSlug: string\n /** Inferred tenant identifier (if available) */\n tenantSlug?: string\n /** Current Payload request */\n req: {\n payload: {\n find: (args: Record<string, unknown>) => Promise<{ docs?: Array<Record<string, unknown>> }>\n logger?: {\n warn?: (...args: unknown[]) => void\n }\n }\n query?: unknown\n headers?: unknown\n user?: unknown\n }\n}\n\nexport interface ThemeManagementLivePreviewOptions {\n /** Enable Payload admin live preview for the target config (default: true) */\n enabled?: boolean\n /** Inject a Payload endpoint for live preview (enables `/api/theme/preview`) (default: false) */\n injectRoute?: boolean\n /** Endpoint path under Payload API (default: '/theme/preview') */\n routePath?: string\n /** Collection slug containing preview pages (default: 'pages') */\n pageCollection?: string\n /** Preferred page slug for preview (default: 'home') */\n pageSlug?: string\n /** Fallback to first page if preferred slug does not exist (default: true) */\n fallbackToFirstPage?: boolean\n /** Tenant field name used for filtering in multi-tenant setups (default: 'tenant') */\n tenantField?: string\n /** Query param name appended to default URL when tenant is resolved (default: 'tenant') */\n tenantQueryParam?: string\n /**\n * Device breakpoints shown in Payload's Live Preview toolbar (iframe size presets).\n * Use this to make preview sizing more practical for your editors.\n */\n breakpoints?: Array<{\n name: string\n label: string\n width: number | string\n height: number | string\n }>\n /**\n * Custom URL resolver for Payload live preview.\n * Defaults to `/${slug}` (or `/` for `home`) with optional tenant query param.\n */\n url?: (args: ThemeManagementLivePreviewUrlArgs) => string | Promise<string>\n}\n\nexport interface ThemeManagementCacheRevalidationOptions {\n /** Enable cache revalidation support (default: true for standalone mode, false for tab mode) */\n enabled?: boolean\n /** Inject a Payload endpoint for manual/external revalidation triggers (default: true) */\n injectRoute?: boolean\n /** Endpoint path under Payload API (default: '/theme/revalidate') */\n routePath?: string\n /** Optional shared secret checked against header/body/query before revalidation */\n secret?: string\n /** Additional tags to revalidate together with the default global tag */\n tags?: string[]\n /** Optional paths to revalidate together with tags */\n paths?: string[]\n}\n\nexport interface ThemeManagementPluginOptions {\n /** Whether the plugin should register itself */\n enabled?: boolean\n /** Collection slug that stores site-level settings (default: `site-settings`) */\n targetCollection?: string\n /** Create a standalone collection instead of adding as a tab (default: false) */\n useStandaloneCollection?: boolean\n /** Name of the standalone collection (default: 'appearance-settings') */\n standaloneCollectionSlug?: string\n /** Label for the standalone collection (default: 'Appearance Settings') */\n standaloneCollectionLabel?: string | Record<string, string>\n /** Theme presets available to editors */\n themePresets?: ThemePreset[]\n /** Default preset name when no value is stored */\n defaultTheme?: string\n /** Allow editors to toggle between light / dark / auto modes */\n includeColorModeToggle?: boolean\n /** Expose custom CSS editor */\n includeCustomCSS?: boolean\n /** Reserved for future use, keeps API parity */\n includeBrandIdentity?: boolean\n /** Enable advanced controls such as animation level */\n enableAdvancedFeatures?: boolean\n /** Log helpful messages during config mutation */\n enableLogging?: boolean\n /** Configure Payload admin live preview URL generation */\n livePreview?: boolean | ThemeManagementLivePreviewOptions\n /** Configure cache revalidation route and tags for Next.js `unstable_cache` usage */\n cacheRevalidation?: boolean | ThemeManagementCacheRevalidationOptions\n}\n\nexport interface FetchThemeConfigurationOptions {\n /** Optional tenant identifier if your project is multi-tenant */\n tenantSlug?: string\n /** Collection/Global slug override (default: `site-settings`) */\n collectionSlug?: string\n /** Depth parameter passed to Payload REST API */\n depth?: number\n /** Locale parameter passed to Payload REST API */\n locale?: string\n /** Include draft documents */\n draft?: boolean\n /** Extra query parameters to append to the request */\n queryParams?: Record<string, string | number | boolean>\n /** Set to true if using standalone global instead of collection (default: false) */\n useGlobal?: boolean\n}\n"],"names":[],"mappings":"AAuGA,WAeC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kilivi/payloadcms-theme-management",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Theme configuration plugin for Payload CMS v3 with 60+ professional themes and standalone collection support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|