init commit for iPAL-kit plugin

This commit is contained in:
2026-07-18 20:30:23 +02:00
parent 10638127a9
commit 5733a9c8bf
119 changed files with 6892 additions and 411 deletions
+95 -113
View File
@@ -1,113 +1,95 @@
import type { CollectionSlug, Config } from 'payload'
import { customEndpointHandler } from './endpoints/customEndpointHandler.js'
export type IpalKitConfig = {
/**
* List of collections to add a custom field
*/
collections?: Partial<Record<CollectionSlug, true>>
disabled?: boolean
}
export const ipalKit =
(pluginOptions: IpalKitConfig) =>
(config: Config): Config => {
if (!config.collections) {
config.collections = []
}
config.collections.push({
slug: 'plugin-collection',
fields: [
{
name: 'id',
type: 'text',
},
],
})
if (pluginOptions.collections) {
for (const collectionSlug in pluginOptions.collections) {
const collection = config.collections.find(
(collection) => collection.slug === collectionSlug,
)
if (collection) {
collection.fields.push({
name: 'addedByPlugin',
type: 'text',
admin: {
position: 'sidebar',
},
})
}
}
}
/**
* If the plugin is disabled, we still want to keep added collections/fields so the database schema is consistent which is important for migrations.
* If your plugin heavily modifies the database schema, you may want to remove this property.
*/
if (pluginOptions.disabled) {
return config
}
if (!config.endpoints) {
config.endpoints = []
}
if (!config.admin) {
config.admin = {}
}
if (!config.admin.components) {
config.admin.components = {}
}
if (!config.admin.components.beforeDashboard) {
config.admin.components.beforeDashboard = []
}
config.admin.components.beforeDashboard.push(
`ipal-kit/client#BeforeDashboardClient`,
)
config.admin.components.beforeDashboard.push(
`ipal-kit/rsc#BeforeDashboardServer`,
)
config.endpoints.push({
handler: customEndpointHandler,
method: 'get',
path: '/my-plugin-endpoint',
})
const incomingOnInit = config.onInit
config.onInit = async (payload) => {
// Ensure we are executing any existing onInit functions before running our own.
if (incomingOnInit) {
await incomingOnInit(payload)
}
const { totalDocs } = await payload.count({
collection: 'plugin-collection',
where: {
id: {
equals: 'seeded-by-plugin',
},
},
})
if (totalDocs === 0) {
await payload.create({
collection: 'plugin-collection',
data: {
id: 'seeded-by-plugin',
},
})
}
}
return config
}
export type { AccessOption, Role } from './modules/access/index.js'
export {
adminOnly,
adminOnlyField,
adminOrEditor,
adminOrEditorField,
adminOrSelf,
authenticated,
hasMinimumRole,
isAdmin,
isEditor,
requireRole,
requireRoleField,
ROLE_HIERARCHY,
} from './modules/access/index.js'
export type { AnalyticsConfig } from './modules/analytics/index.js'
export { getAnalyticsConfig } from './modules/analytics/index.js'
export {
ACCEPT_ALL_CONSENT,
CONSENT_CATEGORIES,
CONSENT_COOKIE,
CONSENT_MAX_AGE,
CONSENT_VERSION,
DEFAULT_CONSENT,
getConsentTexts,
parseConsent,
REJECT_ALL_CONSENT,
serializeConsent,
setDefaultConsent,
updateConsent,
} from './modules/consent/index.js'
export type { ConsentCategory, ConsentState, ConsentTexts } from './modules/consent/index.js'
export type {
ContentCollectionOption,
ContentOption,
ResolvedRoute,
} from './modules/content/index.js'
export {
archiveFieldName,
buildArchivePath,
buildEntryPath,
getArchiveEntries,
parsePageParam,
resolveRoute,
} from './modules/content/index.js'
export type { ArchiveEntries } from './modules/content/index.js'
// Imported straight from the file, NOT from ./modules/email/index.js — that
// barrel re-exports sendEmail, which imports 'server-only' and would crash when
// Payload loads the config (or runs generate:importmap) as a plain Node script.
export { panelSmtpAdapter } from './modules/email/panelSmtpAdapter.js'
export type { PanelSmtpAdapterArgs } from './modules/email/panelSmtpAdapter.js'
export { buildFormsPlugin } from './modules/forms/formsPluginConfig.js'
export type {
FormsCollectionOverrides,
FormsFieldsOverride,
FormsOption,
} from './modules/forms/types.js'
export { createContentHelpers } from './modules/frontend/index.js'
export type { I18nConfig, LocaleDefinition, LocalizedSlugs } from './modules/i18n/index.js'
export {
buildLocalizedPath,
getDefaultLocale,
getLocaleCodes,
getLocaleDefinition,
getLocalizedSlugs,
isValidLocale,
LOCALE_COOKIE_NAME,
matchAcceptLanguage,
negotiateLocale,
switchLocalePath,
} from './modules/i18n/index.js'
export type { LocaleMiddlewareResult } from './modules/i18n/index.js'
export { createLocaleMiddleware, DEFAULT_MIDDLEWARE_MATCHER } from './modules/i18n/index.js'
export type { PagesOption, SystemPageRole } from './modules/pages/index.js'
export { ALL_SYSTEM_PAGE_ROLES, getSystemPagePath } from './modules/pages/index.js'
export type { GlobalQueryOptions } from './modules/payload/index.js'
export {
getGlobal,
getSiteIntegrations,
getSiteSettings,
SITE_INTEGRATIONS_SLUG,
SITE_SETTINGS_SLUG,
} from './modules/payload/index.js'
export type { PageMetadata, SeoMeta, SeoOption } from './modules/seo/index.js'
export { buildHreflangAlternates, buildMetadata, composeTitle } from './modules/seo/index.js'
export type { AutoFillMapping } from './modules/seo/index.js'
export {
buildAutoFillMetaHook,
createMetadataGenerator,
createPageMetadata,
injectAutoFillMeta,
} from './modules/seo/index.js'
export { buildSlugField, toSlug } from './modules/slug/index.js'
export { default as ipalKit } from './plugin.js'
export type { IpalOptions } from './types.js'