@justanarthur/payload-www 2.2.8 → 2.3.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/README.md CHANGED
@@ -20,7 +20,7 @@ The composition root is `createWWWConfig()` — see [Quick start](#quick-start)
20
20
  | Fields | [`/fields`](#fields) | `link`, `linkGroup` (with `disableLabel` / `appearances` / `localized` / `relationTo` / `extraFields`), `slugField`, `appearanceOptions`. |
21
21
  | Access | [`/access`](#access) | `anyone`, `authenticated`, `authenticatedOrPublished`. |
22
22
  | Caching | [`Caching`](#caching) | Cached query getters wrap `@pro-laico/payload-revalidate` finders; tag-based invalidation via `revalidatePlugin()`; `seedPayloadCache` singleton seed. |
23
- | Metadata | [`/metadata`](#metadata) | `buildArticleLd`, `buildBreadcrumbsLd`, `buildOrganizationLd`, `buildWebSiteLd`, `buildProductLd`, `buildRootJsonLd`; slug transforms; `queryDocBySlug`, `queryDocByID`, `queryGlobal`, `queryAllDocs`, `queryAllLocaleSlugs`; `seedPayloadCache`, `tagsFor`. |
23
+ | Metadata | [`/metadata`](#metadata) | `buildArticleLd`, `buildBreadcrumbsLd`, `buildOrganizationLd`, `buildWebSiteLd`, `buildProductLd`, `buildRootJsonLd`; slug transforms; `queryDocBySlug`, `queryDocByID`, `queryGlobal`, `queryDocs`, `queryAllDocs`, `queryAllLocaleSlugs`; `seedPayloadCache`, `tagsFor`. |
24
24
  | Next.js page renderers | [`/render-pages`](#render-pages) | `createCollectionPageExports`, `createRootLayoutExports`; default render components `PagesPage`, `PostsPage`, `HeaderPage`, `FooterPage`, `RootJsonLd`. |
25
25
  | Sitemap | [`/sitemap`](#sitemap) | `createSitemapFromCollections` (Next.js file-convention helper). |
26
26
  | Plugin re-exports | [`/imagehash`](#plugin-re-exports), [`/translator`](#plugin-re-exports) | Drop-in for hosts that don't want to import the sibling packages directly. |
@@ -144,6 +144,7 @@ const { default: PostPage, generateMetadata, generateStaticParams } = createColl
144
144
  | `routing` | `RoutingConfig` | required | `{ locales, defaultLocale, localePrefix, labels? }` from `next-intl/routing`'s `defineRouting` |
145
145
  | `slug` | `string` | `'pages'` | collection slug to query |
146
146
  | `slugShape` | `'single' \| 'catch-all'` | `'single'` | drives `generateStaticParams` + slug segmentation |
147
+ | `depth` | `number` | `2` | relationship / upload hops populated on the rendered document. `0` hands every media and relationship field to the render component as a bare id. Enumeration (`generateStaticParams`, `generateSitemap`) stays at `0` regardless. |
147
148
 
148
149
  ### `createCollectionPageExports(args, deps)` — deps
149
150
 
@@ -171,6 +172,7 @@ const { default: PostPage, generateMetadata, generateStaticParams } = createColl
171
172
  | `config` | `Promise<SanitizedConfig>` | required |
172
173
  | `importMap` | `ImportMap` | required |
173
174
  | `routing` | `RoutingConfig` | required |
175
+ | `depth` | `number` | relationship / upload hops populated on the `header` + `footer` globals. Defaults to `2`. |
174
176
 
175
177
  | dep | type | notes |
176
178
  |---|---|---|
@@ -253,8 +255,8 @@ in the host's `revalidatePlugin()` registration (see [Caching](#caching) below).
253
255
 
254
256
  ### Caching
255
257
 
256
- The lib's cached query layer (`queryDocBySlug`, `queryGlobal`, `queryAllDocs`, `queryAllLocaleSlugs`,
257
- `queryDocByID`) wraps `@pro-laico/payload-revalidate`'s finders in `'use cache'` + `cacheLife('weeks')`
258
+ The lib's cached query layer (`queryDocBySlug`, `queryGlobal`, `queryDocs`, `queryAllDocs`,
259
+ `queryAllLocaleSlugs`, `queryDocByID`) wraps `@pro-laico/payload-revalidate`'s finders in `'use cache'` + `cacheLife('weeks')`
258
260
  scopes. Setup:
259
261
 
260
262
  1. **Install the peer deps at the workspace root** (not in the lib's `dependencies` — `file:` links
@@ -301,6 +303,34 @@ scopes. Setup:
301
303
  seedPayloadCache({ config })
302
304
  ```
303
305
 
306
+ 6. **List with `queryDocs`, never a raw `payload.find`** — a read inside `'use cache'` that
307
+ doesn't go through the finders carries no tags, so nothing the admin does can bust it.
308
+ `queryDocs` tags list membership plus every returned doc and what is populated into it:
309
+
310
+ ```ts
311
+ import { queryDocs } from '@justanarthur/payload-www/metadata'
312
+
313
+ const { docs, totalPages } = await queryDocs({
314
+ collectionSlug: 'posts',
315
+ locale,
316
+ sort: '-publishedAt',
317
+ limit: 10,
318
+ depth: 1,
319
+ list: 'archive'
320
+ })
321
+ ```
322
+
323
+ `list` names a scope whose sort and filter fields are declared on the plugin, so moving a
324
+ post's date or category reorders the archive even when that post wasn't on the page:
325
+
326
+ ```ts
327
+ createWWWConfig().withWWWConfig({
328
+ defaultPluginsConfigs: {
329
+ revalidate: { collections: { posts: { lists: { archive: ['publishedAt', 'categories'] } } } }
330
+ }
331
+ })
332
+ ```
333
+
304
334
  The cached profile is `cacheLife('weeks')` — Next 16's built-in long-tail profile (5 m stale,
305
335
  1 w revalidate, 30 d expire). No custom `cacheLife` config entry needed. Invalidations are
306
336
  purely tag-based: `revalidatePlugin()` fires the same tags the finders emit, so every save /
@@ -344,6 +374,7 @@ import {
344
374
  queryDocBySlug, // cached collection fetch
345
375
  queryDocByID, // cached collection fetch by id
346
376
  queryGlobal, // cached global fetch
377
+ queryDocs, // cached, tagged listing (where / sort / limit / page)
347
378
  queryAllDocs, // for generateStaticParams
348
379
  queryAllLocaleSlugs, // for hreflang alternates
349
380
  seedPayloadCache, // one-time seed for the pro-laico cache helpers
@@ -396,7 +427,7 @@ The package's `package.json#exports` map:
396
427
  | `@justanarthur/payload-www/collections` | `createWWWCollectionGlobal`, `queryDoc` |
397
428
  | `@justanarthur/payload-www/fields` | `link`, `linkGroup`, `appearanceOptions`, `slugField`, `LinkAppearances`, `LinkOptions` |
398
429
  | `@justanarthur/payload-www/access` | `anyone`, `authenticated`, `authenticatedOrPublished` |
399
- | `@justanarthur/payload-www/metadata` | `buildArticleLd`, `buildBreadcrumbsLd`, `buildOrganizationLd`, `buildWebSiteLd`, `buildProductLd`, `buildRootJsonLd`, `queryDocBySlug`, `queryDocByID`, `queryGlobal`, `queryAllDocs`, `queryAllLocaleSlugs`, `seedPayloadCache`, `tagsFor`, `paramsSlugToSlug`, `slugToParamsSlug` + types |
430
+ | `@justanarthur/payload-www/metadata` | `buildArticleLd`, `buildBreadcrumbsLd`, `buildOrganizationLd`, `buildWebSiteLd`, `buildProductLd`, `buildRootJsonLd`, `queryDocBySlug`, `queryDocByID`, `queryGlobal`, `queryDocs`, `queryAllDocs`, `queryAllLocaleSlugs`, `seedPayloadCache`, `tagsFor`, `paramsSlugToSlug`, `slugToParamsSlug` + types |
400
431
  | `@justanarthur/payload-www/utils` | `generateImportName`, `getFromImportMap` |
401
432
  | `@justanarthur/payload-www/imagehash` | `imageHashPlugin`, `BlurhashPluginOptions` (re-export of `@justanarthur/payload-imagehash-plugin`) |
402
433
  | `@justanarthur/payload-www/translator` | `translator` (re-export of `@justanarthur/payload-plugin-translator`) |
@@ -20,6 +20,7 @@ type QueryDocArgs = ({
20
20
  globalSlug: string;
21
21
  locale: string;
22
22
  draft?: boolean;
23
+ depth?: number;
23
24
  }) | ({
24
25
  collectionSlug: string;
25
26
  slug: string;
@@ -119,7 +119,7 @@ function seedPayloadCache({ config }) {
119
119
  return;
120
120
  _seedPromise = (async () => {
121
121
  const payload = await getPayload({ config: await config });
122
- _helpers = createCacheHelpers(payload);
122
+ _helpers = { ...createCacheHelpers(payload), payload };
123
123
  })();
124
124
  }
125
125
  async function requireCacheHelpers() {
@@ -132,6 +132,7 @@ async function requireCacheHelpers() {
132
132
  }
133
133
  throw new Error("[payload-www] seedPayloadCache({ config }) must be called before any query getter. " + "Call it from createCollectionPageExports / createRootLayoutExports factory, or in your root layout.");
134
134
  }
135
+ var RENDER_DEPTH = 2;
135
136
  async function queryDocBySlug(args) {
136
137
  "use cache";
137
138
  cacheLife("weeks");
@@ -142,7 +143,7 @@ async function queryDocBySlug(args) {
142
143
  locale: args.locale,
143
144
  draft: args.draft ?? false,
144
145
  overrideAccess: args.draft ?? false,
145
- depth: args.depth
146
+ depth: args.depth ?? RENDER_DEPTH
146
147
  });
147
148
  const result = await find(args.slug);
148
149
  const doc = result ?? (isIndexSlug(args.slug) ? await find(null) : null);
@@ -156,7 +157,7 @@ async function queryGlobal(args) {
156
157
  const result = await findGlobal(args.globalSlug, {
157
158
  locale: args.locale,
158
159
  draft: args.draft ?? false,
159
- depth: args.depth
160
+ depth: args.depth ?? RENDER_DEPTH
160
161
  });
161
162
  return result ?? null;
162
163
  } catch (error) {
@@ -172,9 +173,31 @@ async function queryAllDocs(args) {
172
173
  const { ids } = await findIds(collection, { locale: args.locale, pagination: false, overrideAccess: false });
173
174
  if (ids.length === 0)
174
175
  return [];
175
- const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false })));
176
+ const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false, depth: 0 })));
176
177
  return docs.filter((d) => d !== null);
177
178
  }
179
+ async function queryDocs({
180
+ collectionSlug,
181
+ list,
182
+ draft = false,
183
+ depth = RENDER_DEPTH,
184
+ ...find
185
+ }) {
186
+ "use cache";
187
+ cacheLife("weeks");
188
+ const { payload, cacheIds, cacheDoc } = await requireCacheHelpers();
189
+ const collection = collectionSlug;
190
+ const result = await payload.find({ ...find, collection, draft, depth, overrideAccess: draft });
191
+ await cacheIds(result, collection, { list, draft });
192
+ for (const doc of result.docs)
193
+ await cacheDoc(doc, collection, { draft });
194
+ return {
195
+ docs: result.docs,
196
+ totalDocs: result.totalDocs,
197
+ totalPages: result.totalPages,
198
+ page: result.page ?? 1
199
+ };
200
+ }
178
201
  async function queryDoc(args) {
179
202
  if ("globalSlug" in args)
180
203
  return queryGlobal(args);
@@ -199,7 +222,7 @@ async function queryDocByID(args) {
199
222
  locale: args.locale,
200
223
  draft: args.draft ?? false,
201
224
  overrideAccess: args.draft ?? false,
202
- depth: args.depth
225
+ depth: args.depth ?? RENDER_DEPTH
203
226
  });
204
227
  }
205
228
 
package/dist/config.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { CollectionConfig, Config, GlobalConfig, Plugin } from "payload";
2
2
  import { MCPPluginConfig } from "@payloadcms/plugin-mcp";
3
+ import { RevalidatePluginOptions } from "@pro-laico/payload-revalidate";
3
4
  import { SEOPluginConfig } from "@justanarthur/payload-plugin-seo/types";
4
5
  import { BlurhashPluginOptions } from "@justanarthur/payload-imagehash-plugin/types";
5
6
  import { TranslatorConfig } from "@justanarthur/payload-plugin-translator/types";
@@ -15,7 +16,7 @@ type WWWInputConfig = Omit<Config, "collections" | "globals" | "plugins"> & {
15
16
  imageHash?: MergeOrOverride<BlurhashPluginOptions>;
16
17
  translator?: MergeOrOverride<TranslatorConfig>;
17
18
  mcp?: MergeOrOverride<MCPPluginConfig>;
18
- revalidate?: false | (<D>(d: D) => D);
19
+ revalidate?: false | MergeOrOverride<RevalidatePluginOptions>;
19
20
  };
20
21
  };
21
22
  declare function createWWWConfig(): WWWConfigApi;
package/dist/config.js CHANGED
@@ -317,6 +317,7 @@ import { revalidatePlugin } from "@pro-laico/payload-revalidate";
317
317
  function createWWWConfig() {
318
318
  function withWWWConfig(input) {
319
319
  const { defaultPluginsConfigs, ...config } = input;
320
+ const revalidate = defaultPluginsConfigs?.revalidate;
320
321
  const blocks = config.blocks || [];
321
322
  const collections = mergeOrOverride([
322
323
  createPagesCollection(blocks),
@@ -362,7 +363,7 @@ function createWWWConfig() {
362
363
  ];
363
364
  const plugins = [
364
365
  ...mergeOrOverride(defaultPlugins, config.plugins),
365
- revalidatePlugin()
366
+ revalidatePlugin(revalidate === false ? { enabled: false } : mergeOrOverride({}, revalidate))
366
367
  ];
367
368
  return {
368
369
  ...config,
@@ -22,7 +22,7 @@ declare function paramsSlugToSlug(slug: string | string[] | undefined, _shape: S
22
22
  declare function slugToParamsSlug(slug: string, shape: SlugShape): string | string[];
23
23
  declare function isIndexSlug(slug: string | null | undefined): boolean;
24
24
  declare function shapeHasIndexPath(shape: SlugShape): boolean;
25
- import { DataFromCollectionSlug, DataFromGlobalSlug, SanitizedConfig } from "payload";
25
+ import { DataFromCollectionSlug, DataFromGlobalSlug, SanitizedConfig, SelectType, Sort, Where } from "payload";
26
26
  import { tagsFor } from "@pro-laico/payload-revalidate";
27
27
  type SeedPayloadCacheArgs = {
28
28
  config: SanitizedConfig | Promise<SanitizedConfig>;
@@ -47,9 +47,28 @@ type QueryListArgs<S extends string> = {
47
47
  slugField?: string;
48
48
  locale: string;
49
49
  };
50
+ type QueryDocsArgs<S extends string> = {
51
+ collectionSlug: S;
52
+ locale: string;
53
+ where?: Where;
54
+ sort?: Sort;
55
+ limit?: number;
56
+ page?: number;
57
+ depth?: number;
58
+ select?: SelectType;
59
+ draft?: boolean;
60
+ list?: string;
61
+ };
62
+ type QueryDocsResult<S extends string> = {
63
+ docs: DataFromCollectionSlug<S>[];
64
+ totalDocs: number;
65
+ totalPages: number;
66
+ page: number;
67
+ };
50
68
  declare function queryDocBySlug<S extends string>(args: QueryCollectionArgs<S>): Promise<DataFromCollectionSlug<S> | null>;
51
69
  declare function queryGlobal<G extends string>(args: QueryGlobalArgs<G>): Promise<DataFromGlobalSlug<G> | null>;
52
70
  declare function queryAllDocs<S extends string = string>(args: QueryListArgs<S>): Promise<DataFromCollectionSlug<S>[]>;
71
+ declare function queryDocs<S extends string>({ collectionSlug, list, draft, depth,...find }: QueryDocsArgs<S>): Promise<QueryDocsResult<S>>;
53
72
  declare function queryAllLocaleSlugs(args: {
54
73
  collectionSlug: string;
55
74
  id: number | string;
@@ -74,6 +93,7 @@ declare const metadata: {
74
93
  queryDocBySlug: typeof queryDocBySlug;
75
94
  queryDocByID: typeof queryDocByID;
76
95
  queryGlobal: typeof queryGlobal;
96
+ queryDocs: typeof queryDocs;
77
97
  queryAllDocs: typeof queryAllDocs;
78
98
  queryAllLocaleSlugs: typeof queryAllLocaleSlugs;
79
99
  paramsSlugToSlug: typeof paramsSlugToSlug;
@@ -83,4 +103,4 @@ declare const metadata: {
83
103
  seedPayloadCache: typeof seedPayloadCache;
84
104
  tagsFor: (payload: Payload_eipjla) => Tags_1jpdl;
85
105
  };
86
- export { ArticleLdOptions, BreadcrumbItem, BuildOrganizationLdOptions, BuildProductLdOptions, BuildRootJsonLdOptions, BuildWebSiteLdOptions, SeedPayloadCacheArgs, SlugShape, buildArticleLd, buildBreadcrumbsLd, buildOrganizationLd, buildProductLd, buildRootJsonLd, buildWebSiteLd, metadata as default, isIndexSlug, paramsSlugToSlug, queryAllDocs, queryAllLocaleSlugs, queryDocByID, queryDocBySlug, queryGlobal, seedPayloadCache, shapeHasIndexPath, slugToParamsSlug, tagsFor };
106
+ export { ArticleLdOptions, BreadcrumbItem, BuildOrganizationLdOptions, BuildProductLdOptions, BuildRootJsonLdOptions, BuildWebSiteLdOptions, QueryDocsArgs, QueryDocsResult, SeedPayloadCacheArgs, SlugShape, buildArticleLd, buildBreadcrumbsLd, buildOrganizationLd, buildProductLd, buildRootJsonLd, buildWebSiteLd, metadata as default, isIndexSlug, paramsSlugToSlug, queryAllDocs, queryAllLocaleSlugs, queryDocByID, queryDocBySlug, queryDocs, queryGlobal, seedPayloadCache, shapeHasIndexPath, slugToParamsSlug, tagsFor };
package/dist/metadata.js CHANGED
@@ -127,7 +127,7 @@ function seedPayloadCache({ config }) {
127
127
  return;
128
128
  _seedPromise = (async () => {
129
129
  const payload = await getPayload({ config: await config });
130
- _helpers = createCacheHelpers(payload);
130
+ _helpers = { ...createCacheHelpers(payload), payload };
131
131
  })();
132
132
  }
133
133
  async function requireCacheHelpers() {
@@ -140,6 +140,7 @@ async function requireCacheHelpers() {
140
140
  }
141
141
  throw new Error("[payload-www] seedPayloadCache({ config }) must be called before any query getter. " + "Call it from createCollectionPageExports / createRootLayoutExports factory, or in your root layout.");
142
142
  }
143
+ var RENDER_DEPTH = 2;
143
144
  async function queryDocBySlug(args) {
144
145
  "use cache";
145
146
  cacheLife("weeks");
@@ -150,7 +151,7 @@ async function queryDocBySlug(args) {
150
151
  locale: args.locale,
151
152
  draft: args.draft ?? false,
152
153
  overrideAccess: args.draft ?? false,
153
- depth: args.depth
154
+ depth: args.depth ?? RENDER_DEPTH
154
155
  });
155
156
  const result = await find(args.slug);
156
157
  const doc = result ?? (isIndexSlug(args.slug) ? await find(null) : null);
@@ -164,7 +165,7 @@ async function queryGlobal(args) {
164
165
  const result = await findGlobal(args.globalSlug, {
165
166
  locale: args.locale,
166
167
  draft: args.draft ?? false,
167
- depth: args.depth
168
+ depth: args.depth ?? RENDER_DEPTH
168
169
  });
169
170
  return result ?? null;
170
171
  } catch (error) {
@@ -180,9 +181,31 @@ async function queryAllDocs(args) {
180
181
  const { ids } = await findIds(collection, { locale: args.locale, pagination: false, overrideAccess: false });
181
182
  if (ids.length === 0)
182
183
  return [];
183
- const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false })));
184
+ const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false, depth: 0 })));
184
185
  return docs.filter((d) => d !== null);
185
186
  }
187
+ async function queryDocs({
188
+ collectionSlug,
189
+ list,
190
+ draft = false,
191
+ depth = RENDER_DEPTH,
192
+ ...find
193
+ }) {
194
+ "use cache";
195
+ cacheLife("weeks");
196
+ const { payload, cacheIds, cacheDoc } = await requireCacheHelpers();
197
+ const collection = collectionSlug;
198
+ const result = await payload.find({ ...find, collection, draft, depth, overrideAccess: draft });
199
+ await cacheIds(result, collection, { list, draft });
200
+ for (const doc of result.docs)
201
+ await cacheDoc(doc, collection, { draft });
202
+ return {
203
+ docs: result.docs,
204
+ totalDocs: result.totalDocs,
205
+ totalPages: result.totalPages,
206
+ page: result.page ?? 1
207
+ };
208
+ }
186
209
  async function queryDoc(args) {
187
210
  if ("globalSlug" in args)
188
211
  return queryGlobal(args);
@@ -207,7 +230,7 @@ async function queryDocByID(args) {
207
230
  locale: args.locale,
208
231
  draft: args.draft ?? false,
209
232
  overrideAccess: args.draft ?? false,
210
- depth: args.depth
233
+ depth: args.depth ?? RENDER_DEPTH
211
234
  });
212
235
  }
213
236
 
@@ -222,6 +245,7 @@ var metadata = {
222
245
  queryDocBySlug,
223
246
  queryDocByID,
224
247
  queryGlobal,
248
+ queryDocs,
225
249
  queryAllDocs,
226
250
  queryAllLocaleSlugs,
227
251
  paramsSlugToSlug,
@@ -246,6 +270,7 @@ export {
246
270
  queryAllLocaleSlugs,
247
271
  queryDocByID,
248
272
  queryDocBySlug,
273
+ queryDocs,
249
274
  queryGlobal,
250
275
  seedPayloadCache,
251
276
  shapeHasIndexPath,
package/dist/pages.d.ts CHANGED
@@ -39,6 +39,8 @@ type CreateCollectionPageExportsArgs<S extends string = "pages"> = {
39
39
  importMap: ImportMap3;
40
40
  routing: RoutingConfig;
41
41
  slugShape?: SlugShape;
42
+ /** Relationship / upload hops populated on the rendered document. `0` renders them as bare ids. */
43
+ depth?: number;
42
44
  };
43
45
  type CreateCollectionPageExportsDeps<S extends string> = {
44
46
  getServerSideURL: () => string;
@@ -46,7 +48,7 @@ type CreateCollectionPageExportsDeps<S extends string> = {
46
48
  /** Rendered while the document streams. Defaults to nothing. */
47
49
  fallback?: ReactNode2;
48
50
  };
49
- declare function createCollectionPageExports<S extends string = "pages">({ slug: collectionSlug, _payloadConfig, importMap, routing, slugShape }: CreateCollectionPageExportsArgs<S>, { getServerSideURL, pagePathPrefix, fallback }: CreateCollectionPageExportsDeps<S>): {
51
+ declare function createCollectionPageExports<S extends string = "pages">({ slug: collectionSlug, _payloadConfig, importMap, routing, slugShape, depth }: CreateCollectionPageExportsArgs<S>, { getServerSideURL, pagePathPrefix, fallback }: CreateCollectionPageExportsDeps<S>): {
50
52
  default: (props: NextPageProps) => Promise<ReactNode2>;
51
53
  generateMetadata: (props: NextPageProps) => Promise<Metadata>;
52
54
  generateStaticParams: (props: GenerateStaticParamsProps) => Promise<{
package/dist/pages.js CHANGED
@@ -212,7 +212,7 @@ function seedPayloadCache({ config }) {
212
212
  return;
213
213
  _seedPromise = (async () => {
214
214
  const payload = await getPayload({ config: await config });
215
- _helpers = createCacheHelpers(payload);
215
+ _helpers = { ...createCacheHelpers(payload), payload };
216
216
  })();
217
217
  }
218
218
  async function requireCacheHelpers() {
@@ -225,6 +225,7 @@ async function requireCacheHelpers() {
225
225
  }
226
226
  throw new Error("[payload-www] seedPayloadCache({ config }) must be called before any query getter. " + "Call it from createCollectionPageExports / createRootLayoutExports factory, or in your root layout.");
227
227
  }
228
+ var RENDER_DEPTH = 2;
228
229
  async function queryDocBySlug(args) {
229
230
  "use cache";
230
231
  cacheLife("weeks");
@@ -235,7 +236,7 @@ async function queryDocBySlug(args) {
235
236
  locale: args.locale,
236
237
  draft: args.draft ?? false,
237
238
  overrideAccess: args.draft ?? false,
238
- depth: args.depth
239
+ depth: args.depth ?? RENDER_DEPTH
239
240
  });
240
241
  const result = await find(args.slug);
241
242
  const doc = result ?? (isIndexSlug(args.slug) ? await find(null) : null);
@@ -249,7 +250,7 @@ async function queryGlobal(args) {
249
250
  const result = await findGlobal(args.globalSlug, {
250
251
  locale: args.locale,
251
252
  draft: args.draft ?? false,
252
- depth: args.depth
253
+ depth: args.depth ?? RENDER_DEPTH
253
254
  });
254
255
  return result ?? null;
255
256
  } catch (error) {
@@ -265,9 +266,31 @@ async function queryAllDocs(args) {
265
266
  const { ids } = await findIds(collection, { locale: args.locale, pagination: false, overrideAccess: false });
266
267
  if (ids.length === 0)
267
268
  return [];
268
- const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false })));
269
+ const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false, depth: 0 })));
269
270
  return docs.filter((d) => d !== null);
270
271
  }
272
+ async function queryDocs({
273
+ collectionSlug,
274
+ list,
275
+ draft = false,
276
+ depth = RENDER_DEPTH,
277
+ ...find
278
+ }) {
279
+ "use cache";
280
+ cacheLife("weeks");
281
+ const { payload, cacheIds, cacheDoc } = await requireCacheHelpers();
282
+ const collection = collectionSlug;
283
+ const result = await payload.find({ ...find, collection, draft, depth, overrideAccess: draft });
284
+ await cacheIds(result, collection, { list, draft });
285
+ for (const doc of result.docs)
286
+ await cacheDoc(doc, collection, { draft });
287
+ return {
288
+ docs: result.docs,
289
+ totalDocs: result.totalDocs,
290
+ totalPages: result.totalPages,
291
+ page: result.page ?? 1
292
+ };
293
+ }
271
294
  async function queryDoc(args) {
272
295
  if ("globalSlug" in args)
273
296
  return queryGlobal(args);
@@ -292,7 +315,7 @@ async function queryDocByID(args) {
292
315
  locale: args.locale,
293
316
  draft: args.draft ?? false,
294
317
  overrideAccess: args.draft ?? false,
295
- depth: args.depth
318
+ depth: args.depth ?? RENDER_DEPTH
296
319
  });
297
320
  }
298
321
 
@@ -368,7 +391,8 @@ function createCollectionPageExports({
368
391
  _payloadConfig,
369
392
  importMap,
370
393
  routing,
371
- slugShape = "single"
394
+ slugShape = "single",
395
+ depth = RENDER_DEPTH
372
396
  }, {
373
397
  getServerSideURL,
374
398
  pagePathPrefix,
@@ -380,6 +404,7 @@ function createCollectionPageExports({
380
404
  return queryDoc({
381
405
  slug,
382
406
  locale,
407
+ depth,
383
408
  collectionSlug
384
409
  });
385
410
  }
@@ -48,6 +48,8 @@ type CreateCollectionPageExportsArgs<S extends string = "pages"> = {
48
48
  importMap: ImportMap3;
49
49
  routing: RoutingConfig;
50
50
  slugShape?: SlugShape;
51
+ /** Relationship / upload hops populated on the rendered document. `0` renders them as bare ids. */
52
+ depth?: number;
51
53
  };
52
54
  type CreateCollectionPageExportsDeps<S extends string> = {
53
55
  getServerSideURL: () => string;
@@ -55,7 +57,7 @@ type CreateCollectionPageExportsDeps<S extends string> = {
55
57
  /** Rendered while the document streams. Defaults to nothing. */
56
58
  fallback?: ReactNode2;
57
59
  };
58
- declare function createCollectionPageExports<S extends string = "pages">({ slug: collectionSlug, _payloadConfig, importMap, routing, slugShape }: CreateCollectionPageExportsArgs<S>, { getServerSideURL, pagePathPrefix, fallback }: CreateCollectionPageExportsDeps<S>): {
60
+ declare function createCollectionPageExports<S extends string = "pages">({ slug: collectionSlug, _payloadConfig, importMap, routing, slugShape, depth }: CreateCollectionPageExportsArgs<S>, { getServerSideURL, pagePathPrefix, fallback }: CreateCollectionPageExportsDeps<S>): {
59
61
  default: (props: NextPageProps) => Promise<ReactNode2>;
60
62
  generateMetadata: (props: NextPageProps) => Promise<Metadata>;
61
63
  generateStaticParams: (props: GenerateStaticParamsProps) => Promise<{
@@ -75,6 +77,8 @@ type CreateRootLayoutExportsArgs = {
75
77
  _payloadConfig: Promise<SanitizedConfig3>;
76
78
  importMap: ImportMap4;
77
79
  routing: RoutingConfig;
80
+ /** Relationship / upload hops populated on the header and footer globals. `0` renders them as bare ids. */
81
+ depth?: number;
78
82
  };
79
83
  type CreateRootLayoutProvidersArgs = {
80
84
  children: ReactNode3;
@@ -86,7 +90,7 @@ type CreateRootLayoutExportsDeps = {
86
90
  getServerSideURL?: () => string;
87
91
  };
88
92
  type Element_12xgc2 = JSX_1kxb2["Element"];
89
- declare function createRootLayoutExports({ _payloadConfig, importMap, routing }: CreateRootLayoutExportsArgs, { providers, htmlAttrs, getServerSideURL }?: CreateRootLayoutExportsDeps): {
93
+ declare function createRootLayoutExports({ _payloadConfig, importMap, routing, depth }: CreateRootLayoutExportsArgs, { providers, htmlAttrs, getServerSideURL }?: CreateRootLayoutExportsDeps): {
90
94
  default: (props: NextLayoutProps) => Promise<Element_12xgc2>;
91
95
  generateStaticParams: () => {
92
96
  locale: string;
@@ -242,7 +242,7 @@ function seedPayloadCache({ config }) {
242
242
  return;
243
243
  _seedPromise = (async () => {
244
244
  const payload = await getPayload({ config: await config });
245
- _helpers = createCacheHelpers(payload);
245
+ _helpers = { ...createCacheHelpers(payload), payload };
246
246
  })();
247
247
  }
248
248
  async function requireCacheHelpers() {
@@ -255,6 +255,7 @@ async function requireCacheHelpers() {
255
255
  }
256
256
  throw new Error("[payload-www] seedPayloadCache({ config }) must be called before any query getter. " + "Call it from createCollectionPageExports / createRootLayoutExports factory, or in your root layout.");
257
257
  }
258
+ var RENDER_DEPTH = 2;
258
259
  async function queryDocBySlug(args) {
259
260
  "use cache";
260
261
  cacheLife("weeks");
@@ -265,7 +266,7 @@ async function queryDocBySlug(args) {
265
266
  locale: args.locale,
266
267
  draft: args.draft ?? false,
267
268
  overrideAccess: args.draft ?? false,
268
- depth: args.depth
269
+ depth: args.depth ?? RENDER_DEPTH
269
270
  });
270
271
  const result = await find(args.slug);
271
272
  const doc = result ?? (isIndexSlug(args.slug) ? await find(null) : null);
@@ -279,7 +280,7 @@ async function queryGlobal(args) {
279
280
  const result = await findGlobal(args.globalSlug, {
280
281
  locale: args.locale,
281
282
  draft: args.draft ?? false,
282
- depth: args.depth
283
+ depth: args.depth ?? RENDER_DEPTH
283
284
  });
284
285
  return result ?? null;
285
286
  } catch (error) {
@@ -295,9 +296,31 @@ async function queryAllDocs(args) {
295
296
  const { ids } = await findIds(collection, { locale: args.locale, pagination: false, overrideAccess: false });
296
297
  if (ids.length === 0)
297
298
  return [];
298
- const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false })));
299
+ const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false, depth: 0 })));
299
300
  return docs.filter((d) => d !== null);
300
301
  }
302
+ async function queryDocs({
303
+ collectionSlug,
304
+ list,
305
+ draft = false,
306
+ depth = RENDER_DEPTH,
307
+ ...find
308
+ }) {
309
+ "use cache";
310
+ cacheLife("weeks");
311
+ const { payload, cacheIds, cacheDoc } = await requireCacheHelpers();
312
+ const collection = collectionSlug;
313
+ const result = await payload.find({ ...find, collection, draft, depth, overrideAccess: draft });
314
+ await cacheIds(result, collection, { list, draft });
315
+ for (const doc of result.docs)
316
+ await cacheDoc(doc, collection, { draft });
317
+ return {
318
+ docs: result.docs,
319
+ totalDocs: result.totalDocs,
320
+ totalPages: result.totalPages,
321
+ page: result.page ?? 1
322
+ };
323
+ }
301
324
  async function queryDoc(args) {
302
325
  if ("globalSlug" in args)
303
326
  return queryGlobal(args);
@@ -322,7 +345,7 @@ async function queryDocByID(args) {
322
345
  locale: args.locale,
323
346
  draft: args.draft ?? false,
324
347
  overrideAccess: args.draft ?? false,
325
- depth: args.depth
348
+ depth: args.depth ?? RENDER_DEPTH
326
349
  });
327
350
  }
328
351
 
@@ -398,7 +421,8 @@ function createCollectionPageExports({
398
421
  _payloadConfig,
399
422
  importMap,
400
423
  routing,
401
- slugShape = "single"
424
+ slugShape = "single",
425
+ depth = RENDER_DEPTH
402
426
  }, {
403
427
  getServerSideURL,
404
428
  pagePathPrefix,
@@ -410,6 +434,7 @@ function createCollectionPageExports({
410
434
  return queryDoc({
411
435
  slug,
412
436
  locale,
437
+ depth,
413
438
  collectionSlug
414
439
  });
415
440
  }
@@ -535,7 +560,8 @@ async function resolveLocale(props) {
535
560
  function createRootLayoutExports({
536
561
  _payloadConfig,
537
562
  importMap,
538
- routing
563
+ routing,
564
+ depth = RENDER_DEPTH
539
565
  }, {
540
566
  providers,
541
567
  htmlAttrs,
@@ -553,8 +579,8 @@ function createRootLayoutExports({
553
579
  header,
554
580
  footer
555
581
  ] = await Promise.all([
556
- queryDoc({ globalSlug: "header", locale }),
557
- queryDoc({ globalSlug: "footer", locale })
582
+ queryDoc({ globalSlug: "header", locale, depth }),
583
+ queryDoc({ globalSlug: "footer", locale, depth })
558
584
  ]);
559
585
  const renderedHeader = renderWWWDataModule(header, { collectionSlug: "header", configPath: "globals", config: _payloadConfig, importMap }, { ...props, locale }), renderedFooter = renderWWWDataModule(footer, { collectionSlug: "footer", configPath: "globals", config: _payloadConfig, importMap }, { ...props, locale });
560
586
  const mergedHtmlAttrs = {
package/dist/sitemap.js CHANGED
@@ -37,7 +37,7 @@ function seedPayloadCache({ config }) {
37
37
  return;
38
38
  _seedPromise = (async () => {
39
39
  const payload = await getPayload({ config: await config });
40
- _helpers = createCacheHelpers(payload);
40
+ _helpers = { ...createCacheHelpers(payload), payload };
41
41
  })();
42
42
  }
43
43
  async function requireCacheHelpers() {
@@ -50,6 +50,7 @@ async function requireCacheHelpers() {
50
50
  }
51
51
  throw new Error("[payload-www] seedPayloadCache({ config }) must be called before any query getter. " + "Call it from createCollectionPageExports / createRootLayoutExports factory, or in your root layout.");
52
52
  }
53
+ var RENDER_DEPTH = 2;
53
54
  async function queryDocBySlug(args) {
54
55
  "use cache";
55
56
  cacheLife("weeks");
@@ -60,7 +61,7 @@ async function queryDocBySlug(args) {
60
61
  locale: args.locale,
61
62
  draft: args.draft ?? false,
62
63
  overrideAccess: args.draft ?? false,
63
- depth: args.depth
64
+ depth: args.depth ?? RENDER_DEPTH
64
65
  });
65
66
  const result = await find(args.slug);
66
67
  const doc = result ?? (isIndexSlug(args.slug) ? await find(null) : null);
@@ -74,7 +75,7 @@ async function queryGlobal(args) {
74
75
  const result = await findGlobal(args.globalSlug, {
75
76
  locale: args.locale,
76
77
  draft: args.draft ?? false,
77
- depth: args.depth
78
+ depth: args.depth ?? RENDER_DEPTH
78
79
  });
79
80
  return result ?? null;
80
81
  } catch (error) {
@@ -90,9 +91,31 @@ async function queryAllDocs(args) {
90
91
  const { ids } = await findIds(collection, { locale: args.locale, pagination: false, overrideAccess: false });
91
92
  if (ids.length === 0)
92
93
  return [];
93
- const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false })));
94
+ const docs = await Promise.all(ids.map((id) => findDocByID(collection, id, { locale: args.locale, overrideAccess: false, depth: 0 })));
94
95
  return docs.filter((d) => d !== null);
95
96
  }
97
+ async function queryDocs({
98
+ collectionSlug,
99
+ list,
100
+ draft = false,
101
+ depth = RENDER_DEPTH,
102
+ ...find
103
+ }) {
104
+ "use cache";
105
+ cacheLife("weeks");
106
+ const { payload, cacheIds, cacheDoc } = await requireCacheHelpers();
107
+ const collection = collectionSlug;
108
+ const result = await payload.find({ ...find, collection, draft, depth, overrideAccess: draft });
109
+ await cacheIds(result, collection, { list, draft });
110
+ for (const doc of result.docs)
111
+ await cacheDoc(doc, collection, { draft });
112
+ return {
113
+ docs: result.docs,
114
+ totalDocs: result.totalDocs,
115
+ totalPages: result.totalPages,
116
+ page: result.page ?? 1
117
+ };
118
+ }
96
119
  async function queryDoc(args) {
97
120
  if ("globalSlug" in args)
98
121
  return queryGlobal(args);
@@ -117,7 +140,7 @@ async function queryDocByID(args) {
117
140
  locale: args.locale,
118
141
  draft: args.draft ?? false,
119
142
  overrideAccess: args.draft ?? false,
120
- depth: args.depth
143
+ depth: args.depth ?? RENDER_DEPTH
121
144
  });
122
145
  }
123
146
 
@@ -214,7 +237,8 @@ function createCollectionPageExports({
214
237
  _payloadConfig,
215
238
  importMap,
216
239
  routing,
217
- slugShape = "single"
240
+ slugShape = "single",
241
+ depth = RENDER_DEPTH
218
242
  }, {
219
243
  getServerSideURL,
220
244
  pagePathPrefix,
@@ -226,6 +250,7 @@ function createCollectionPageExports({
226
250
  return queryDoc({
227
251
  slug,
228
252
  locale,
253
+ depth,
229
254
  collectionSlug
230
255
  });
231
256
  }
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@justanarthur/payload-www",
3
3
  "description": "Reusable Payload CMS website template — config builder, collections, globals, blocks, fields, access, hooks, metadata (JSON-LD, hreflang), page renderers, and test helpers.",
4
- "version": "2.2.8",
4
+ "version": "2.3.0",
5
+ "license": "MIT",
5
6
  "type": "module",
6
7
  "private": false,
7
8
  "files": [