add dist
This commit is contained in:
+64
@@ -0,0 +1,64 @@
|
||||
import type { BasePayload, SanitizedConfig } from 'payload';
|
||||
import type { ArchiveEntries, ContentOption, ResolvedRoute } from '../content/index.js';
|
||||
import type { I18nConfig } from '../i18n/index.js';
|
||||
import type { RobotsRules, SitemapEntry } from '../seo/index.js';
|
||||
type CreateContentHelpersArgs = {
|
||||
/**
|
||||
* Absolute site origin for sitemap/robots URLs. Falls back to
|
||||
* NEXT_PUBLIC_SERVER_URL, then to a relative origin (which most crawlers
|
||||
* reject, so set one in production).
|
||||
*/
|
||||
baseUrl?: string;
|
||||
/**
|
||||
* The client's payload config promise (the default export of payload.config).
|
||||
* Passed in because the plugin never imports the client's config directly.
|
||||
*/
|
||||
config: Promise<SanitizedConfig> | SanitizedConfig;
|
||||
/** Archive-backed collections, same value as the plugin option. */
|
||||
content?: ContentOption;
|
||||
/**
|
||||
* i18n config. Required only if you want the ready-made `sitemap` / `robots`
|
||||
* handlers — they need the locale list to emit hreflang.
|
||||
*/
|
||||
i18n?: I18nConfig;
|
||||
/** Pages collection slug. Defaults to 'pages'. */
|
||||
pagesSlug?: string;
|
||||
/** SiteSettings global slug. Defaults to 'site-settings'. */
|
||||
settingsSlug?: string;
|
||||
};
|
||||
/**
|
||||
* Bundles the per-request data helpers a frontend needs — the same cached
|
||||
* wrappers every project was writing by hand (getPayload, settings, locale
|
||||
* list, route resolution, archive entries).
|
||||
*
|
||||
* Everything is wrapped in React `cache()`, so within one request a value is
|
||||
* fetched once no matter how many times it's asked for — which matters because
|
||||
* Next runs generateMetadata and the page component separately, and both hit
|
||||
* these. Crucially the Payload instance is cached *here*, once, so every helper
|
||||
* shares it; that's why this is a factory and not loose functions importing a
|
||||
* shared module.
|
||||
*
|
||||
* ```ts
|
||||
* // src/lib/content.ts
|
||||
* import { createContentHelpers } from 'ipal-kit'
|
||||
* import config from '@/payload.config'
|
||||
* import { contentConfig } from '@/content.config'
|
||||
*
|
||||
* export const { getCachedPayload, getSettings, getConfiguredLocales, resolveRoute, getEntries } =
|
||||
* createContentHelpers({ config, content: contentConfig })
|
||||
* ```
|
||||
*
|
||||
* `resolveRoute` and `getEntries` are separate on purpose: routing decides what
|
||||
* a URL is, fetching gets the listing. Metadata generation needs the first and
|
||||
* not the second, and a page component composes them in two obvious lines.
|
||||
*/
|
||||
export declare function createContentHelpers({ baseUrl, config, content, i18n, pagesSlug, settingsSlug, }: CreateContentHelpersArgs): {
|
||||
getCachedPayload: () => Promise<BasePayload>;
|
||||
getConfiguredLocales: () => Promise<string[]>;
|
||||
getEntries: (collection: string, locale: string, page: number, perPage: number) => Promise<ArchiveEntries>;
|
||||
getSettings: (locale: string) => Promise<import("payload").JsonObject>;
|
||||
resolveRoute: (locale: string, segments: string[] | undefined, page: number) => Promise<null | ResolvedRoute>;
|
||||
robots: () => RobotsRules;
|
||||
sitemap: () => Promise<SitemapEntry[]>;
|
||||
};
|
||||
export {};
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
import { getPayload } from 'payload';
|
||||
import { cache } from 'react';
|
||||
import { getArchiveEntries, resolveRoute as resolveRouteRaw } from '../content/index.js';
|
||||
import { buildRobots, buildSitemapEntries } from '../seo/index.js';
|
||||
/**
|
||||
* Bundles the per-request data helpers a frontend needs — the same cached
|
||||
* wrappers every project was writing by hand (getPayload, settings, locale
|
||||
* list, route resolution, archive entries).
|
||||
*
|
||||
* Everything is wrapped in React `cache()`, so within one request a value is
|
||||
* fetched once no matter how many times it's asked for — which matters because
|
||||
* Next runs generateMetadata and the page component separately, and both hit
|
||||
* these. Crucially the Payload instance is cached *here*, once, so every helper
|
||||
* shares it; that's why this is a factory and not loose functions importing a
|
||||
* shared module.
|
||||
*
|
||||
* ```ts
|
||||
* // src/lib/content.ts
|
||||
* import { createContentHelpers } from 'ipal-kit'
|
||||
* import config from '@/payload.config'
|
||||
* import { contentConfig } from '@/content.config'
|
||||
*
|
||||
* export const { getCachedPayload, getSettings, getConfiguredLocales, resolveRoute, getEntries } =
|
||||
* createContentHelpers({ config, content: contentConfig })
|
||||
* ```
|
||||
*
|
||||
* `resolveRoute` and `getEntries` are separate on purpose: routing decides what
|
||||
* a URL is, fetching gets the listing. Metadata generation needs the first and
|
||||
* not the second, and a page component composes them in two obvious lines.
|
||||
*/ export function createContentHelpers({ baseUrl, config, content, i18n, pagesSlug = 'pages', settingsSlug = 'site-settings' }) {
|
||||
const origin = baseUrl ?? process.env.NEXT_PUBLIC_SERVER_URL ?? '';
|
||||
const getCachedPayload = cache(async ()=>getPayload({
|
||||
config: await config
|
||||
}));
|
||||
const getConfiguredLocales = cache(async ()=>{
|
||||
const c = await config;
|
||||
return c.localization ? c.localization.locales.map((l)=>l.code) : [];
|
||||
});
|
||||
const getSettings = cache(async (locale)=>{
|
||||
const payload = await getCachedPayload();
|
||||
return payload.findGlobal({
|
||||
slug: settingsSlug,
|
||||
depth: 2,
|
||||
locale: locale
|
||||
});
|
||||
});
|
||||
/** What does this URL point at? Routing only — no listing data. */ const resolveRoute = cache(async (locale, segments, page)=>{
|
||||
const payload = await getCachedPayload();
|
||||
return resolveRouteRaw({
|
||||
content,
|
||||
locale,
|
||||
page,
|
||||
pagesSlug,
|
||||
payload,
|
||||
segments,
|
||||
settingsSlug
|
||||
});
|
||||
});
|
||||
/** One page of a collection's entries, for an archive listing. */ const getEntries = cache(async (collection, locale, page, perPage)=>{
|
||||
const payload = await getCachedPayload();
|
||||
return getArchiveEntries({
|
||||
collection,
|
||||
locale,
|
||||
page,
|
||||
payload,
|
||||
perPage
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Ready-made handler for Next's `app/sitemap.ts` — every page and entry with
|
||||
* per-URL hreflang and lastmod. Re-export it directly:
|
||||
*
|
||||
* ```ts
|
||||
* // app/sitemap.ts
|
||||
* export { sitemap as default } from '@/lib/content'
|
||||
* ```
|
||||
*/ const sitemap = cache(async ()=>{
|
||||
if (!i18n) {
|
||||
throw new Error('[ipal] createContentHelpers: pass `i18n` to use the sitemap handler.');
|
||||
}
|
||||
return buildSitemapEntries({
|
||||
baseUrl: origin,
|
||||
config: i18n,
|
||||
content,
|
||||
pagesSlug,
|
||||
payload: await getCachedPayload(),
|
||||
settingsSlug
|
||||
});
|
||||
});
|
||||
/**
|
||||
* Ready-made handler for Next's `app/robots.ts`. Re-export directly:
|
||||
*
|
||||
* ```ts
|
||||
* // app/robots.ts
|
||||
* export { robots as default } from '@/lib/content'
|
||||
* ```
|
||||
*/ const robots = ()=>buildRobots({
|
||||
baseUrl: origin
|
||||
});
|
||||
return {
|
||||
getCachedPayload,
|
||||
getConfiguredLocales,
|
||||
getEntries,
|
||||
getSettings,
|
||||
resolveRoute,
|
||||
robots,
|
||||
sitemap
|
||||
};
|
||||
}
|
||||
|
||||
//# sourceMappingURL=createContentHelpers.js.map
|
||||
File diff suppressed because one or more lines are too long
Vendored
+1
@@ -0,0 +1 @@
|
||||
export { createContentHelpers } from './createContentHelpers.js';
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
export { createContentHelpers } from './createContentHelpers.js';
|
||||
|
||||
//# sourceMappingURL=index.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/modules/frontend/index.ts"],"sourcesContent":["export { createContentHelpers } from './createContentHelpers.js'\n"],"names":["createContentHelpers"],"mappings":"AAAA,SAASA,oBAAoB,QAAQ,4BAA2B"}
|
||||
Reference in New Issue
Block a user