@justanarthur/payload-www 0.3.5 → 1.2.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 +317 -307
- package/dist/access.d.ts +2 -2
- package/dist/access.js +3 -17
- package/dist/blocks.d.ts +7 -12
- package/dist/blocks.js +24 -43
- package/dist/cli.js +201 -0
- package/dist/collections.d.ts +33 -225
- package/dist/collections.js +185 -639
- package/dist/config.d.ts +19 -105
- package/dist/config.js +257 -855
- package/dist/fields.d.ts +4 -46
- package/dist/fields.js +177 -53
- package/dist/imagehash.js +0 -15
- package/dist/import-map-provider.d.ts +0 -16
- package/dist/import-map-provider.js +0 -15
- package/dist/metadata.d.ts +24 -89
- package/dist/metadata.js +123 -255
- package/dist/pages.d.ts +37 -319
- package/dist/pages.js +349 -964
- package/dist/render-pages.d.ts +70 -565
- package/dist/render-pages.js +464 -1477
- package/dist/sitemap.d.ts +10 -0
- package/dist/sitemap.js +337 -0
- package/dist/translator.js +0 -15
- package/dist/utils.d.ts +10 -12
- package/dist/utils.js +18 -41
- package/package.json +81 -178
- package/dist/components.d.ts +0 -6
- package/dist/components.js +0 -39
- package/dist/core-access.d.ts +0 -11
- package/dist/core-access.js +0 -34
- package/dist/core-blocks.d.ts +0 -24
- package/dist/core-blocks.js +0 -79
- package/dist/core-fields.d.ts +0 -73
- package/dist/core-fields.js +0 -167
- package/dist/core-utils.d.ts +0 -16
- package/dist/core-utils.js +0 -63
- package/dist/data-collections.d.ts +0 -229
- package/dist/data-collections.js +0 -676
- package/dist/data-seed.d.ts +0 -76
- package/dist/data-seed.js +0 -212
- package/dist/data-test.d.ts +0 -30
- package/dist/data-test.js +0 -1110
- package/dist/globals.d.ts +0 -69
- package/dist/globals.js +0 -251
- package/dist/hooks.d.ts +0 -108
- package/dist/hooks.js +0 -228
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -39
- package/dist/render-components.d.ts +0 -42
- package/dist/render-components.js +0 -154
- package/dist/render-metadata.d.ts +0 -122
- package/dist/render-metadata.js +0 -390
- package/dist/render-utils.d.ts +0 -166
- package/dist/render-utils.js +0 -398
- package/dist/seed.d.ts +0 -76
- package/dist/seed.js +0 -212
- package/dist/server.d.ts +0 -980
- package/dist/server.js +0 -2231
- package/dist/test.d.ts +0 -30
- package/dist/test.js +0 -1110
- package/dist/with-www-config.d.ts +0 -108
- package/dist/with-www-config.js +0 -1006
package/dist/config.js
CHANGED
|
@@ -1,450 +1,185 @@
|
|
|
1
1
|
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __returnValue = (v) => v;
|
|
4
|
-
function __exportSetter(name, newValue) {
|
|
5
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
-
}
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, {
|
|
10
|
-
get: all[name],
|
|
11
|
-
enumerable: true,
|
|
12
|
-
configurable: true,
|
|
13
|
-
set: __exportSetter.bind(all, name)
|
|
14
|
-
});
|
|
15
|
-
};
|
|
16
|
-
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
2
|
|
|
18
|
-
// src/
|
|
19
|
-
|
|
20
|
-
var authenticated = ({ req: { user } }) => Boolean(user);
|
|
21
|
-
var authenticatedOrPublished = ({ req: { user } }) => {
|
|
22
|
-
if (user)
|
|
23
|
-
return true;
|
|
24
|
-
return { _status: { equals: "published" } };
|
|
25
|
-
};
|
|
3
|
+
// src/createWWWConfig.ts
|
|
4
|
+
import openAIResolver from "@justanarthur/payload-plugin-translator/resolvers/openAI";
|
|
26
5
|
|
|
27
|
-
//
|
|
28
|
-
var
|
|
29
|
-
var NESTED_PATTERN = /^[a-z0-9_-]+$/;
|
|
30
|
-
var slugField = (options = {}) => {
|
|
31
|
-
const { name = "slug", nested = false, localized = true } = options;
|
|
32
|
-
const pattern = nested ? NESTED_PATTERN : FLAT_PATTERN;
|
|
33
|
-
const invalidMessage = nested ? "Slug must be lowercase, with hyphens or the `_` nesting divider (no spaces or other special characters)" : "Slug must be lowercase, with hyphens (no spaces or special characters)";
|
|
34
|
-
return {
|
|
35
|
-
name,
|
|
36
|
-
type: "text",
|
|
37
|
-
required: true,
|
|
38
|
-
unique: true,
|
|
39
|
-
index: true,
|
|
40
|
-
localized,
|
|
41
|
-
admin: {
|
|
42
|
-
position: "sidebar",
|
|
43
|
-
...nested ? { description: "Lowercase, hyphens for words. Use the `_` divider for nesting, e.g. `about_us` → `/about/us`." } : {}
|
|
44
|
-
},
|
|
45
|
-
validate: (value) => {
|
|
46
|
-
if (typeof value !== "string")
|
|
47
|
-
return "Slug must be a string";
|
|
48
|
-
if (value !== "" && !pattern.test(value))
|
|
49
|
-
return invalidMessage;
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
};
|
|
6
|
+
// package.json
|
|
7
|
+
var name = "@justanarthur/payload-www";
|
|
54
8
|
|
|
55
|
-
// src/
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
console.log("[WWW] render/_locale:prefixFor locale=", locale, "default=", defaultLocale, "mode=", mode, "->", JSON.stringify(result));
|
|
65
|
-
return result;
|
|
66
|
-
}
|
|
67
|
-
function resolveLocale(req) {
|
|
68
|
-
if (!req || typeof req !== "object") {
|
|
69
|
-
console.log('[WWW] render/_locale:resolveLocale -> "" (no req)');
|
|
70
|
-
return "";
|
|
71
|
-
}
|
|
72
|
-
const r = req;
|
|
73
|
-
if (typeof r.locale === "string" && r.locale.length > 0) {
|
|
74
|
-
console.log("[WWW] render/_locale:resolveLocale ->", r.locale, "(from req.locale)");
|
|
75
|
-
return r.locale;
|
|
76
|
-
}
|
|
77
|
-
const fallback = r.payload?.config?.localization?.defaultLocale;
|
|
78
|
-
if (typeof fallback === "string" && fallback.length > 0) {
|
|
79
|
-
console.log("[WWW] render/_locale:resolveLocale ->", fallback, "(from config.localization.defaultLocale)");
|
|
80
|
-
return fallback;
|
|
81
|
-
}
|
|
82
|
-
console.log('[WWW] render/_locale:resolveLocale -> "" (no locale anywhere)');
|
|
83
|
-
return "";
|
|
84
|
-
}
|
|
85
|
-
function allLocales(req) {
|
|
86
|
-
if (!req || typeof req !== "object") {
|
|
87
|
-
console.log("[WWW] render/_locale:allLocales -> [] (no req)");
|
|
88
|
-
return [];
|
|
89
|
-
}
|
|
90
|
-
const r = req;
|
|
91
|
-
const list = r.payload?.config?.localization?.locales;
|
|
92
|
-
if (!Array.isArray(list) || list.length === 0) {
|
|
93
|
-
console.log("[WWW] render/_locale:allLocales -> [] (no locales declared)");
|
|
94
|
-
return [];
|
|
95
|
-
}
|
|
96
|
-
const out = [];
|
|
97
|
-
for (const entry of list) {
|
|
98
|
-
if (typeof entry === "string" && entry.length > 0) {
|
|
99
|
-
out.push(entry);
|
|
100
|
-
} else if (entry && typeof entry === "object" && "code" in entry) {
|
|
101
|
-
const code = entry.code;
|
|
102
|
-
if (typeof code === "string" && code.length > 0)
|
|
103
|
-
out.push(code);
|
|
9
|
+
// src/collections/hooks/populatePublishedAt.ts
|
|
10
|
+
var populatePublishedAt = ({ data, operation, req }) => {
|
|
11
|
+
if (operation === "create" || operation === "update") {
|
|
12
|
+
if (req.data && !req.data.publishedAt) {
|
|
13
|
+
const now = new Date;
|
|
14
|
+
return {
|
|
15
|
+
...data,
|
|
16
|
+
publishedAt: now
|
|
17
|
+
};
|
|
104
18
|
}
|
|
105
19
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// src/render/hooks/_shared.ts
|
|
111
|
-
var cachePromise = null;
|
|
112
|
-
function nextCacheImport() {
|
|
113
|
-
return cachePromise ??= import("next/cache");
|
|
114
|
-
}
|
|
115
|
-
function shouldSkipRevalidate(context) {
|
|
116
|
-
const skip = Boolean(context?.disableRevalidate);
|
|
117
|
-
if (skip)
|
|
118
|
-
console.log("[WWW] render/hooks:_shared:shouldSkipRevalidate -> skip");
|
|
119
|
-
return skip;
|
|
120
|
-
}
|
|
121
|
-
async function safeRevalidatePath(payload, path) {
|
|
122
|
-
console.log("[WWW] render/hooks:_shared:safeRevalidatePath path=", path);
|
|
123
|
-
try {
|
|
124
|
-
const { revalidatePath } = await nextCacheImport();
|
|
125
|
-
revalidatePath(path);
|
|
126
|
-
} catch (error) {
|
|
127
|
-
console.error("[WWW] render/hooks:_shared:safeRevalidatePath failed path=", path, "err=", String(error));
|
|
128
|
-
payload.logger.error(`revalidatePath("${path}") failed: ${String(error)}`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
async function safeRevalidateTag(payload, tag, profile = "max") {
|
|
132
|
-
console.log("[WWW] render/hooks:_shared:safeRevalidateTag tag=", tag, "profile=", profile);
|
|
133
|
-
try {
|
|
134
|
-
const { revalidateTag } = await nextCacheImport();
|
|
135
|
-
revalidateTag(tag, profile);
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.error("[WWW] render/hooks:_shared:safeRevalidateTag failed tag=", tag, "err=", String(error));
|
|
138
|
-
payload.logger.error(`revalidateTag("${tag}") failed: ${String(error)}`);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
20
|
+
return data;
|
|
21
|
+
};
|
|
141
22
|
|
|
142
|
-
// src/
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const mode = modeOption ?? "always";
|
|
156
|
-
const defaultLocale = defaultLocaleOption ?? req?.payload?.config?.localization?.defaultLocale ?? "";
|
|
157
|
-
return { mode, defaultLocale };
|
|
158
|
-
};
|
|
159
|
-
const localesToFanOut = (req) => {
|
|
160
|
-
const all = allLocales(req);
|
|
161
|
-
if (all.length > 0)
|
|
162
|
-
return all;
|
|
163
|
-
const single = resolveLocale(req);
|
|
164
|
-
return single ? [single] : [];
|
|
165
|
-
};
|
|
166
|
-
const collectionPath = (slug, locale, mode, defaultLocale) => {
|
|
167
|
-
const prefix = prefixFor(locale, defaultLocale, mode);
|
|
168
|
-
if (!slug)
|
|
169
|
-
return `${prefix}${urlPathPrefix}` || "/";
|
|
170
|
-
return `${prefix}${urlPathPrefix}/${slug}`;
|
|
171
|
-
};
|
|
172
|
-
const fanOutPaths = async (payload, req, slug, label) => {
|
|
173
|
-
const { mode, defaultLocale } = resolveDefaults(req);
|
|
174
|
-
const locales = localesToFanOut(req);
|
|
175
|
-
for (const locale of locales) {
|
|
176
|
-
const path = collectionPath(slug, locale, mode, defaultLocale);
|
|
177
|
-
payload.logger.info?.(`${label} ${path}`);
|
|
178
|
-
await safeRevalidatePath(payload, path);
|
|
179
|
-
}
|
|
180
|
-
};
|
|
181
|
-
const fireCollectionTags = async (payload, docId, req) => {
|
|
182
|
-
console.log("[WWW] render/hooks:fireCollectionTags collectionSlug=", collectionSlug, "docId=", docId);
|
|
183
|
-
if (typeof docId === "string" || typeof docId === "number") {
|
|
184
|
-
await safeRevalidateTag(payload, `collection_${collectionSlug}_${docId}`);
|
|
185
|
-
}
|
|
186
|
-
if (resolvedSitemapTag !== false) {
|
|
187
|
-
await safeRevalidateTag(payload, resolvedSitemapTag);
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
const afterChange = async ({ doc, previousDoc, req }) => {
|
|
191
|
-
if (shouldSkipRevalidate(req.context))
|
|
192
|
-
return doc;
|
|
193
|
-
const { payload } = req;
|
|
194
|
-
const typed = doc;
|
|
195
|
-
const prev = previousDoc;
|
|
196
|
-
console.log("[WWW] render/hooks:afterChange collectionSlug=", collectionSlug, "id=", typed.id, "slug=", typed.slug, "prevSlug=", prev?.slug);
|
|
197
|
-
const isPublished = typed._status === "published";
|
|
198
|
-
const wasPublished = prev?._status === "published";
|
|
199
|
-
const prevSlugIsString = typeof prev?.slug === "string";
|
|
200
|
-
const slugChanged = prevSlugIsString && prev?.slug !== typed.slug;
|
|
201
|
-
if (isPublished) {
|
|
202
|
-
if (pathMode !== "tag-only") {
|
|
203
|
-
await fanOutPaths(payload, req, typed.slug, `Revalidating ${collectionSlug} at path:`);
|
|
23
|
+
// src/collections/hooks/createRevalidateCollectionGlobalHook.ts
|
|
24
|
+
import { revalidateTag } from "next/cache";
|
|
25
|
+
function createRevalidateCollectionGlobalHook() {
|
|
26
|
+
const afterChangeDeleteHook = async ({ doc, req, ...args }) => {
|
|
27
|
+
const previousDoc = "previousDoc" in args ? args.previousDoc : null, locale = req.locale;
|
|
28
|
+
function revalidate(args2) {
|
|
29
|
+
try {
|
|
30
|
+
revalidateTag(createCollectionCacheKey({ ...args2, locale }), "max");
|
|
31
|
+
} catch (error) {
|
|
32
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
33
|
+
if (msg.includes("static generation store missing"))
|
|
34
|
+
return;
|
|
35
|
+
console.error(error);
|
|
204
36
|
}
|
|
205
|
-
await fireCollectionTags(payload, typed.id, req);
|
|
206
37
|
}
|
|
207
|
-
if (
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
38
|
+
if ("collection" in args) {
|
|
39
|
+
[
|
|
40
|
+
doc && doc._status !== "draft" && doc.slug,
|
|
41
|
+
previousDoc && previousDoc._status === "published" && previousDoc.slug
|
|
42
|
+
].filter((slug) => slug !== undefined && slug !== false).map((slug) => revalidate({ collectionSlug: args.collection.slug, slug }));
|
|
43
|
+
} else {
|
|
44
|
+
revalidate({ globalSlug: args.global.slug });
|
|
212
45
|
}
|
|
213
46
|
return doc;
|
|
214
47
|
};
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const typed = doc;
|
|
220
|
-
console.log("[WWW] render/hooks:afterDelete collectionSlug=", collectionSlug, "id=", typed?.id, "slug=", typed?.slug);
|
|
221
|
-
if (pathMode !== "tag-only") {
|
|
222
|
-
await fanOutPaths(payload, req, typed?.slug, `Revalidating deleted ${collectionSlug} at path:`);
|
|
223
|
-
}
|
|
224
|
-
await fireCollectionTags(payload, typed?.id, req);
|
|
225
|
-
return doc ?? null;
|
|
226
|
-
};
|
|
227
|
-
return { afterChange, afterDelete };
|
|
48
|
+
return { afterChange: afterChangeDeleteHook, afterDelete: afterChangeDeleteHook };
|
|
49
|
+
}
|
|
50
|
+
function createCollectionCacheKey(args) {
|
|
51
|
+
return `${"globalSlug" in args ? args.globalSlug : args.collectionSlug + args.slug}_${args.locale}`;
|
|
228
52
|
}
|
|
229
|
-
var createRevalidatePageHooks = (opts = {}) => {
|
|
230
|
-
console.log("[WWW] render/hooks:createRevalidatePageHooks (deprecated alias) opts=", JSON.stringify(opts));
|
|
231
|
-
return createRevalidateCollectionHook({
|
|
232
|
-
collectionSlug: "pages",
|
|
233
|
-
urlPathPrefix: "",
|
|
234
|
-
...opts
|
|
235
|
-
});
|
|
236
|
-
};
|
|
237
53
|
|
|
238
|
-
// src/
|
|
239
|
-
var
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
54
|
+
// src/collections/fields/slug.ts
|
|
55
|
+
var slugField = () => ({
|
|
56
|
+
name: "slug",
|
|
57
|
+
type: "text",
|
|
58
|
+
required: true,
|
|
59
|
+
unique: true,
|
|
60
|
+
index: true,
|
|
61
|
+
localized: true,
|
|
62
|
+
admin: {
|
|
63
|
+
position: "sidebar",
|
|
64
|
+
description: "Lowercase, hyphens for words. Use the `_` divider for nesting, e.g. `about_us` → `/about/us`."
|
|
65
|
+
},
|
|
66
|
+
validate: (value) => {
|
|
67
|
+
if (typeof value !== "string")
|
|
68
|
+
return "Slug must be a string";
|
|
69
|
+
if (value !== "" && !/^[a-z0-9_-]+$/.test(value))
|
|
70
|
+
return "Slug must be lowercase, with hyphens (no spaces or special characters).";
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
247
74
|
|
|
248
|
-
// src/
|
|
249
|
-
var
|
|
250
|
-
var
|
|
251
|
-
var
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
localePrefix,
|
|
256
|
-
defaultLocale,
|
|
257
|
-
nested = false
|
|
258
|
-
} = options;
|
|
259
|
-
const baseFields = [
|
|
260
|
-
{
|
|
261
|
-
name: "title",
|
|
262
|
-
type: "text",
|
|
263
|
-
required: true,
|
|
264
|
-
localized: true
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
type: "tabs",
|
|
268
|
-
tabs: [
|
|
269
|
-
{
|
|
270
|
-
fields: [
|
|
271
|
-
{
|
|
272
|
-
name: "blocks",
|
|
273
|
-
type: "blocks",
|
|
274
|
-
blocks,
|
|
275
|
-
required: true,
|
|
276
|
-
admin: { initCollapsed: true }
|
|
277
|
-
}
|
|
278
|
-
],
|
|
279
|
-
label: "Content"
|
|
280
|
-
}
|
|
281
|
-
]
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
name: "publishedAt",
|
|
285
|
-
type: "date",
|
|
286
|
-
admin: { position: "sidebar" }
|
|
287
|
-
},
|
|
288
|
-
slugField({ nested })
|
|
289
|
-
];
|
|
290
|
-
const { afterChange: revalidateAfterChange, afterDelete: revalidateAfterDelete } = createRevalidateCollectionHook({
|
|
291
|
-
collectionSlug,
|
|
292
|
-
urlPathPrefix: "",
|
|
293
|
-
localePrefix,
|
|
294
|
-
defaultLocale
|
|
295
|
-
});
|
|
296
|
-
return {
|
|
297
|
-
slug: collectionSlug,
|
|
298
|
-
custom: { path: renderPath },
|
|
299
|
-
access: {
|
|
300
|
-
create: authenticated,
|
|
301
|
-
delete: authenticated,
|
|
302
|
-
read: authenticatedOrPublished,
|
|
303
|
-
update: authenticated
|
|
304
|
-
},
|
|
305
|
-
fields: baseFields,
|
|
306
|
-
hooks: {
|
|
307
|
-
afterChange: [revalidateAfterChange],
|
|
308
|
-
afterDelete: [revalidateAfterDelete]
|
|
309
|
-
},
|
|
310
|
-
versions: { drafts: { autosave: { interval: 1000 } } }
|
|
311
|
-
};
|
|
75
|
+
// src/collections/access/index.ts
|
|
76
|
+
var anyone = () => true;
|
|
77
|
+
var authenticated = ({ req: { user } }) => Boolean(user);
|
|
78
|
+
var authenticatedOrPublished = ({ req: { user } }) => {
|
|
79
|
+
if (user)
|
|
80
|
+
return true;
|
|
81
|
+
return { _status: { equals: "published" } };
|
|
312
82
|
};
|
|
313
83
|
|
|
314
|
-
// src/
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
defaultLocale
|
|
322
|
-
} = options;
|
|
323
|
-
const baseFields = [
|
|
324
|
-
{
|
|
325
|
-
name: "title",
|
|
326
|
-
type: "text",
|
|
327
|
-
required: true,
|
|
328
|
-
localized: true
|
|
329
|
-
},
|
|
330
|
-
{
|
|
331
|
-
name: "excerpt",
|
|
332
|
-
type: "text",
|
|
333
|
-
required: false,
|
|
334
|
-
localized: true
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
name: "content",
|
|
338
|
-
type: "richText",
|
|
339
|
-
required: false,
|
|
340
|
-
localized: true
|
|
341
|
-
},
|
|
342
|
-
{
|
|
343
|
-
name: "publishedAt",
|
|
344
|
-
type: "date",
|
|
345
|
-
admin: { position: "sidebar" }
|
|
346
|
-
},
|
|
347
|
-
slugField()
|
|
348
|
-
];
|
|
349
|
-
const { afterChange, afterDelete } = createRevalidateCollectionHook({
|
|
350
|
-
collectionSlug,
|
|
351
|
-
urlPathPrefix: "/posts",
|
|
352
|
-
localePrefix,
|
|
353
|
-
defaultLocale
|
|
354
|
-
});
|
|
84
|
+
// src/collections/createWWWCollectionGlobal.ts
|
|
85
|
+
function createWWWCollectionGlobal(fields, {
|
|
86
|
+
slug: collectionSlug,
|
|
87
|
+
renderPath,
|
|
88
|
+
isGlobalConfig = false,
|
|
89
|
+
isDraft = true
|
|
90
|
+
}) {
|
|
355
91
|
return {
|
|
356
92
|
slug: collectionSlug,
|
|
357
|
-
|
|
93
|
+
fields: isGlobalConfig ? fields : [
|
|
94
|
+
slugField(),
|
|
95
|
+
{
|
|
96
|
+
name: "publishedAt",
|
|
97
|
+
type: "date",
|
|
98
|
+
admin: { position: "sidebar" }
|
|
99
|
+
},
|
|
100
|
+
...fields
|
|
101
|
+
],
|
|
102
|
+
custom: { [name]: { path: renderPath } },
|
|
358
103
|
access: {
|
|
359
104
|
create: authenticated,
|
|
360
105
|
delete: authenticated,
|
|
361
|
-
read: authenticatedOrPublished,
|
|
106
|
+
read: isDraft ? authenticatedOrPublished : anyone,
|
|
362
107
|
update: authenticated
|
|
363
108
|
},
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
109
|
+
hooks: (() => {
|
|
110
|
+
const { afterChange, afterDelete } = createRevalidateCollectionGlobalHook();
|
|
111
|
+
return {
|
|
112
|
+
afterChange: [afterChange],
|
|
113
|
+
beforeChange: [populatePublishedAt],
|
|
114
|
+
afterDelete: [afterDelete]
|
|
115
|
+
};
|
|
116
|
+
})(),
|
|
117
|
+
...isDraft && {
|
|
118
|
+
versions: { drafts: { autosave: { interval: 3000 } } }
|
|
119
|
+
}
|
|
370
120
|
};
|
|
371
|
-
}
|
|
121
|
+
}
|
|
372
122
|
|
|
373
|
-
// src/
|
|
374
|
-
var
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
admin: { description: "Admin-only label. Not rendered." }
|
|
414
|
-
},
|
|
123
|
+
// src/collections/createPostsCollection.ts
|
|
124
|
+
var POSTS_SLUG = "posts";
|
|
125
|
+
var POSTS_RENDER_PATH = "@justanarthur/payload-www/render-pages#PostsPage";
|
|
126
|
+
var createPostsCollection = () => createWWWCollectionGlobal([
|
|
127
|
+
{
|
|
128
|
+
name: "title",
|
|
129
|
+
type: "text",
|
|
130
|
+
required: true,
|
|
131
|
+
localized: true
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: "excerpt",
|
|
135
|
+
type: "text",
|
|
136
|
+
required: false,
|
|
137
|
+
localized: true
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "content",
|
|
141
|
+
type: "richText",
|
|
142
|
+
required: false,
|
|
143
|
+
localized: true
|
|
144
|
+
}
|
|
145
|
+
], {
|
|
146
|
+
slug: POSTS_SLUG,
|
|
147
|
+
renderPath: POSTS_RENDER_PATH
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// src/collections/createPagesCollection.ts
|
|
151
|
+
var PAGES_SLUG = "pages";
|
|
152
|
+
var PAGES_RENDER_PATH = "@justanarthur/payload-www/render-pages#PagesPage";
|
|
153
|
+
var createPagesCollection = (blocks) => createWWWCollectionGlobal([
|
|
154
|
+
{
|
|
155
|
+
name: "title",
|
|
156
|
+
type: "text",
|
|
157
|
+
required: true,
|
|
158
|
+
localized: true
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: "tabs",
|
|
162
|
+
tabs: [
|
|
415
163
|
{
|
|
416
|
-
|
|
417
|
-
tabs: [
|
|
164
|
+
fields: [
|
|
418
165
|
{
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
blocks,
|
|
425
|
-
admin: { initCollapsed: true },
|
|
426
|
-
dbName: "b"
|
|
427
|
-
}
|
|
428
|
-
],
|
|
429
|
-
label: "Content"
|
|
166
|
+
name: "blocks",
|
|
167
|
+
type: "blocks",
|
|
168
|
+
blocks,
|
|
169
|
+
required: true,
|
|
170
|
+
admin: { initCollapsed: true }
|
|
430
171
|
}
|
|
431
|
-
]
|
|
432
|
-
|
|
433
|
-
{
|
|
434
|
-
name: "publishedAt",
|
|
435
|
-
type: "date",
|
|
436
|
-
admin: { position: "sidebar" }
|
|
172
|
+
],
|
|
173
|
+
label: "Content"
|
|
437
174
|
}
|
|
438
|
-
]
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
};
|
|
445
|
-
};
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
], {
|
|
178
|
+
slug: PAGES_SLUG,
|
|
179
|
+
renderPath: PAGES_RENDER_PATH
|
|
180
|
+
});
|
|
446
181
|
|
|
447
|
-
// src/
|
|
182
|
+
// src/collections/fields/link.ts
|
|
448
183
|
var appearanceOptions = {
|
|
449
184
|
default: { label: "Default", value: "default" },
|
|
450
185
|
outline: { label: "Outline", value: "outline" }
|
|
@@ -453,8 +188,8 @@ var link = (options = {}) => {
|
|
|
453
188
|
const {
|
|
454
189
|
appearances,
|
|
455
190
|
disableLabel = false,
|
|
456
|
-
relationTo = [PAGES_SLUG],
|
|
457
|
-
localized =
|
|
191
|
+
relationTo = [PAGES_SLUG, POSTS_SLUG],
|
|
192
|
+
localized = true,
|
|
458
193
|
overrides = {},
|
|
459
194
|
extraFields = []
|
|
460
195
|
} = options;
|
|
@@ -539,464 +274,131 @@ var link = (options = {}) => {
|
|
|
539
274
|
return { ...result, ...overrides };
|
|
540
275
|
};
|
|
541
276
|
|
|
542
|
-
// src/
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
{ name: "title", type: "text", required: true, localized: true },
|
|
570
|
-
{ name: "links", type: "array", fields: [link({ appearances: false, localized: true, relationTo: linkRelationTo, extraFields: navColumnLinkFields })] }
|
|
571
|
-
]
|
|
572
|
-
};
|
|
573
|
-
const navItemBlock = {
|
|
574
|
-
slug: "navItem",
|
|
575
|
-
fields: [link({ appearances: false, localized: true, relationTo: linkRelationTo, extraFields: navItemLinkFields })]
|
|
576
|
-
};
|
|
577
|
-
return {
|
|
578
|
-
slug: "header",
|
|
579
|
-
custom: { path: renderPath },
|
|
580
|
-
access: { read: () => true },
|
|
581
|
-
fields: [
|
|
582
|
-
{
|
|
583
|
-
name: "nav",
|
|
584
|
-
type: "blocks",
|
|
585
|
-
required: true,
|
|
586
|
-
blocks: [navColumnBlock, navItemBlock]
|
|
587
|
-
}
|
|
588
|
-
],
|
|
589
|
-
hooks: {
|
|
590
|
-
afterChange: [createRevalidateGlobalHook("header")]
|
|
591
|
-
}
|
|
592
|
-
};
|
|
593
|
-
};
|
|
594
|
-
|
|
595
|
-
// src/data/collections/globals/Footer/config.ts
|
|
596
|
-
var createFooterGlobal = (options = {}) => {
|
|
597
|
-
const {
|
|
598
|
-
renderPath = FOOTER_RENDER_PATH,
|
|
599
|
-
linkRelationTo = [PAGES_SLUG],
|
|
600
|
-
navColumnLinkFields = [],
|
|
601
|
-
navItemLinkFields = []
|
|
602
|
-
} = options;
|
|
603
|
-
const navColumnBlock = {
|
|
604
|
-
slug: "navColumn",
|
|
605
|
-
fields: [
|
|
606
|
-
{ name: "title", type: "text", required: true, localized: true },
|
|
607
|
-
{ name: "links", type: "array", fields: [link({ appearances: false, localized: true, relationTo: linkRelationTo, extraFields: navColumnLinkFields })] }
|
|
608
|
-
]
|
|
609
|
-
};
|
|
610
|
-
const navItemBlock = {
|
|
611
|
-
slug: "navItem",
|
|
612
|
-
fields: [link({ appearances: false, localized: true, relationTo: linkRelationTo, extraFields: navItemLinkFields })]
|
|
613
|
-
};
|
|
614
|
-
return {
|
|
615
|
-
slug: "footer",
|
|
616
|
-
custom: { path: renderPath },
|
|
617
|
-
access: { read: () => true },
|
|
618
|
-
fields: [
|
|
619
|
-
{
|
|
620
|
-
name: "nav",
|
|
621
|
-
type: "blocks",
|
|
622
|
-
required: true,
|
|
623
|
-
blocks: [navColumnBlock, navItemBlock]
|
|
624
|
-
}
|
|
625
|
-
],
|
|
626
|
-
hooks: {
|
|
627
|
-
afterChange: [createRevalidateGlobalHook("footer")]
|
|
628
|
-
}
|
|
629
|
-
};
|
|
630
|
-
};
|
|
631
|
-
|
|
632
|
-
// src/config/createWWWConfig.ts
|
|
633
|
-
import openAIResolver from "@justanarthur/payload-plugin-translator/resolvers/openAI";
|
|
634
|
-
|
|
635
|
-
// src/render/preview/createPreviewHandler.ts
|
|
636
|
-
function createPreviewHandler(options) {
|
|
637
|
-
const { getServerSideURL: _getServerSideURL, secret, enableDraftMode = true } = options;
|
|
638
|
-
return async function GET(req) {
|
|
639
|
-
const { draftMode } = await import("next/headers");
|
|
640
|
-
const { redirect } = await import("next/navigation");
|
|
641
|
-
const url = new URL(req.url);
|
|
642
|
-
const path = url.searchParams.get("path") ?? "/";
|
|
643
|
-
const previewSecret = url.searchParams.get("previewSecret");
|
|
644
|
-
console.log("[WWW] render/preview:createPreviewHandler:GET path=", path, "hasSecret=", Boolean(previewSecret), "enableDraftMode=", enableDraftMode);
|
|
645
|
-
if (!previewSecret || previewSecret !== secret) {
|
|
646
|
-
console.warn("[WWW] render/preview:createPreviewHandler:GET invalid preview secret (401)");
|
|
647
|
-
return new Response("Invalid preview secret", { status: 401 });
|
|
648
|
-
}
|
|
649
|
-
if (enableDraftMode) {
|
|
650
|
-
(await draftMode()).enable();
|
|
651
|
-
console.log("[WWW] render/preview:createPreviewHandler:GET draftMode enabled");
|
|
652
|
-
}
|
|
653
|
-
redirect(path);
|
|
654
|
-
return new Response(null, { status: 204 });
|
|
655
|
-
};
|
|
656
|
-
}
|
|
657
|
-
// src/render/metadata/hreflang.ts
|
|
658
|
-
async function buildHreflangAlternates({
|
|
659
|
-
siteUrl,
|
|
660
|
-
locale,
|
|
661
|
-
urlPrefix,
|
|
662
|
-
storedSlug,
|
|
663
|
-
queryAllLocaleSlugs,
|
|
664
|
-
nested,
|
|
665
|
-
homeSlug,
|
|
666
|
-
defaultLocale,
|
|
667
|
-
locales,
|
|
668
|
-
localePrefix = "always"
|
|
669
|
-
}) {
|
|
670
|
-
const allLocaleSlugs = await queryAllLocaleSlugs(storedSlug, locale);
|
|
671
|
-
console.log("[WWW] render/metadata:buildHreflangAlternates storedSlug=", storedSlug, "locale=", locale, "allLocaleSlugs=", JSON.stringify(allLocaleSlugs));
|
|
672
|
-
const languages = {};
|
|
673
|
-
const urlFor = (l, slug) => {
|
|
674
|
-
const trimmedPrefix = urlPrefix.replace(/^\/|\/$/g, "");
|
|
675
|
-
const prefixSegment = trimmedPrefix ? `/${trimmedPrefix}` : "";
|
|
676
|
-
const urlPath = slug === homeSlug ? "/" : nested ? "/" + slug.replaceAll("_", "/") : "/" + slug;
|
|
677
|
-
const localeSegment = localePrefix === "never" ? "" : localePrefix === "as-needed" && l === defaultLocale ? "" : `/${l}`;
|
|
678
|
-
return `${siteUrl}${localeSegment}${prefixSegment}${urlPath}`;
|
|
679
|
-
};
|
|
680
|
-
for (const l of locales) {
|
|
681
|
-
const slugForLocale = allLocaleSlugs?.[l];
|
|
682
|
-
if (!slugForLocale)
|
|
683
|
-
continue;
|
|
684
|
-
languages[l] = urlFor(l, slugForLocale);
|
|
685
|
-
}
|
|
686
|
-
if (allLocaleSlugs?.[defaultLocale]) {
|
|
687
|
-
languages["x-default"] = urlFor(defaultLocale, allLocaleSlugs[defaultLocale]);
|
|
688
|
-
}
|
|
689
|
-
console.log("[WWW] render/metadata:buildHreflangAlternates ->", JSON.stringify(languages));
|
|
690
|
-
return languages;
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
// src/render/metadata/query.ts
|
|
694
|
-
import { getPayload } from "payload";
|
|
695
|
-
import { cache } from "react";
|
|
696
|
-
|
|
697
|
-
// src/core/utils/getFromImportMap.ts
|
|
698
|
-
function getFromImportMap(key, importMap) {
|
|
699
|
-
return importMap[key.includes("#") ? key : key + "#default"];
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
// src/render/metadata/query.ts
|
|
703
|
-
var queryDocBySlug = cache(async function queryDocBySlug2({
|
|
704
|
-
collectionSlug,
|
|
705
|
-
slug,
|
|
706
|
-
slugField: slugField2 = "slug",
|
|
707
|
-
locale,
|
|
708
|
-
draft = false,
|
|
709
|
-
config
|
|
710
|
-
}) {
|
|
711
|
-
console.log("[WWW] render/metadata:queryDocBySlug collection=", collectionSlug, "slug=", slug, "slugField=", slugField2, "locale=", locale, "draft=", draft);
|
|
712
|
-
const payload = await getPayload({ config });
|
|
713
|
-
const result = await payload.find({
|
|
714
|
-
collection: collectionSlug,
|
|
715
|
-
draft,
|
|
716
|
-
limit: 1,
|
|
717
|
-
pagination: false,
|
|
718
|
-
overrideAccess: draft,
|
|
719
|
-
where: { [slugField2]: { equals: slug } },
|
|
720
|
-
locale
|
|
721
|
-
});
|
|
722
|
-
const doc = result.docs?.[0] ?? null;
|
|
723
|
-
console.log("[WWW] render/metadata:queryDocBySlug ->", doc ? "hit" : "miss");
|
|
724
|
-
return doc;
|
|
725
|
-
});
|
|
726
|
-
var queryAllDocs = cache(async function queryAllDocs2({
|
|
727
|
-
collectionSlug,
|
|
728
|
-
slugField: slugField2 = "slug",
|
|
729
|
-
locale,
|
|
730
|
-
config
|
|
731
|
-
}) {
|
|
732
|
-
console.log("[WWW] render/metadata:queryAllDocs collection=", collectionSlug, "locale=", locale);
|
|
733
|
-
const payload = await getPayload({ config });
|
|
734
|
-
const result = await payload.find({
|
|
735
|
-
collection: collectionSlug,
|
|
736
|
-
draft: false,
|
|
737
|
-
limit: 1000,
|
|
738
|
-
pagination: false,
|
|
739
|
-
overrideAccess: false,
|
|
740
|
-
select: { [slugField2]: true },
|
|
741
|
-
locale
|
|
742
|
-
});
|
|
743
|
-
const docs = result.docs ?? [];
|
|
744
|
-
console.log("[WWW] render/metadata:queryAllDocs -> count=", docs.length);
|
|
745
|
-
return docs;
|
|
746
|
-
});
|
|
747
|
-
var queryAllLocaleSlugs = cache(async function queryAllLocaleSlugs2({
|
|
748
|
-
collectionSlug,
|
|
749
|
-
slug,
|
|
750
|
-
slugField: slugField2 = "slug",
|
|
751
|
-
locale,
|
|
752
|
-
config
|
|
753
|
-
}) {
|
|
754
|
-
console.log("[WWW] render/metadata:queryAllLocaleSlugs collection=", collectionSlug, "slug=", slug, "locale=", locale);
|
|
755
|
-
const payload = await getPayload({ config });
|
|
756
|
-
const result = await payload.find({
|
|
757
|
-
collection: collectionSlug,
|
|
758
|
-
draft: false,
|
|
759
|
-
limit: 1,
|
|
760
|
-
pagination: false,
|
|
761
|
-
overrideAccess: false,
|
|
762
|
-
locale,
|
|
763
|
-
where: { [slugField2]: { equals: slug } },
|
|
764
|
-
select: { [slugField2]: true }
|
|
765
|
-
});
|
|
766
|
-
const doc = result.docs?.[0];
|
|
767
|
-
if (!doc) {
|
|
768
|
-
console.log("[WWW] render/metadata:queryAllLocaleSlugs -> undefined (no doc)");
|
|
769
|
-
return;
|
|
770
|
-
}
|
|
771
|
-
let fieldValue = doc[slugField2];
|
|
772
|
-
if (doc.id != null) {
|
|
773
|
-
const allLocales2 = await payload.findByID({
|
|
774
|
-
collection: collectionSlug,
|
|
775
|
-
id: doc.id,
|
|
776
|
-
locale: "all",
|
|
777
|
-
draft: false,
|
|
778
|
-
overrideAccess: false,
|
|
779
|
-
select: { [slugField2]: true }
|
|
780
|
-
}).catch(() => null);
|
|
781
|
-
if (allLocales2)
|
|
782
|
-
fieldValue = allLocales2[slugField2];
|
|
783
|
-
}
|
|
784
|
-
if (fieldValue && typeof fieldValue === "object") {
|
|
785
|
-
console.log("[WWW] render/metadata:queryAllLocaleSlugs -> localized map=", JSON.stringify(fieldValue));
|
|
786
|
-
return fieldValue;
|
|
277
|
+
// src/collections/createFooterGlobal.ts
|
|
278
|
+
var FOOTER_SLUG = "footer";
|
|
279
|
+
var FOOTER_RENDER_PATH = "@justanarthur/payload-www/render-pages#FooterPage";
|
|
280
|
+
var createFooterGlobal = () => createWWWCollectionGlobal([
|
|
281
|
+
{
|
|
282
|
+
name: "nav",
|
|
283
|
+
type: "blocks",
|
|
284
|
+
required: true,
|
|
285
|
+
blocks: [{
|
|
286
|
+
slug: "navColumn",
|
|
287
|
+
fields: [
|
|
288
|
+
{
|
|
289
|
+
name: "title",
|
|
290
|
+
type: "text",
|
|
291
|
+
required: true,
|
|
292
|
+
localized: true
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: "links",
|
|
296
|
+
type: "array",
|
|
297
|
+
fields: [link({ appearances: false })]
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
}, {
|
|
301
|
+
slug: "navItem",
|
|
302
|
+
fields: [link({ appearances: false })]
|
|
303
|
+
}]
|
|
787
304
|
}
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
out[l] = String(fieldValue ?? slug);
|
|
793
|
-
console.log("[WWW] render/metadata:queryAllLocaleSlugs -> flat-fanout locales=", rawLocales.length, "slug=", JSON.stringify(fieldValue ?? slug));
|
|
794
|
-
return out;
|
|
305
|
+
], {
|
|
306
|
+
slug: FOOTER_SLUG,
|
|
307
|
+
renderPath: FOOTER_RENDER_PATH,
|
|
308
|
+
isGlobalConfig: true
|
|
795
309
|
});
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
310
|
+
|
|
311
|
+
// src/collections/createHeaderGlobal.ts
|
|
312
|
+
var HEADER_SLUG = "header";
|
|
313
|
+
var HEADER_RENDER_PATH = "@justanarthur/payload-www/render-pages#HeaderPage";
|
|
314
|
+
var createHeaderGlobal = () => createWWWCollectionGlobal([
|
|
315
|
+
{
|
|
316
|
+
name: "nav",
|
|
317
|
+
type: "blocks",
|
|
318
|
+
required: true,
|
|
319
|
+
blocks: [{
|
|
320
|
+
slug: "navItem",
|
|
321
|
+
fields: [link({ appearances: false })]
|
|
322
|
+
}, {
|
|
323
|
+
slug: "navColumn",
|
|
324
|
+
fields: [
|
|
325
|
+
{
|
|
326
|
+
name: "title",
|
|
327
|
+
type: "text",
|
|
328
|
+
required: true,
|
|
329
|
+
localized: true
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: "links",
|
|
333
|
+
type: "array",
|
|
334
|
+
fields: [link({ appearances: false, localized: true })]
|
|
335
|
+
}
|
|
336
|
+
]
|
|
337
|
+
}]
|
|
817
338
|
}
|
|
339
|
+
], {
|
|
340
|
+
slug: HEADER_SLUG,
|
|
341
|
+
renderPath: HEADER_RENDER_PATH,
|
|
342
|
+
isGlobalConfig: true
|
|
818
343
|
});
|
|
819
|
-
function getRenderModuleExports(exportName, collection, importMap) {
|
|
820
|
-
const path = collection?.custom?.path;
|
|
821
|
-
if (!path) {
|
|
822
|
-
console.log("[WWW] render/metadata:getRenderModuleExports no custom.path exportName=", exportName);
|
|
823
|
-
return;
|
|
824
|
-
}
|
|
825
|
-
const mod = getFromImportMap(path, importMap);
|
|
826
|
-
const value = mod?.[exportName];
|
|
827
|
-
console.log("[WWW] render/metadata:getRenderModuleExports exportName=", exportName, "path=", path, "hit=", Boolean(value));
|
|
828
|
-
return value;
|
|
829
|
-
}
|
|
830
344
|
|
|
831
|
-
// src/
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
const
|
|
838
|
-
const
|
|
839
|
-
const
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
});
|
|
855
|
-
for (const doc of docs) {
|
|
856
|
-
const storedSlug = doc.slug;
|
|
857
|
-
if (typeof storedSlug !== "string" || storedSlug === "")
|
|
858
|
-
continue;
|
|
859
|
-
const dedupeKey = `${collectionSlug}:${locale}:${storedSlug}`;
|
|
860
|
-
if (seen.has(dedupeKey))
|
|
861
|
-
continue;
|
|
862
|
-
seen.add(dedupeKey);
|
|
863
|
-
const slugPath = isNested ? storedSlug.replaceAll("_", "/") : storedSlug;
|
|
864
|
-
const url = `${siteUrl}${prefixFor(locale, defaultLocale, options.localePrefix ?? "always")}${urlPrefix}/${slugPath}`;
|
|
865
|
-
const languages = await buildHreflangAlternates({
|
|
866
|
-
siteUrl,
|
|
867
|
-
locale,
|
|
868
|
-
urlPrefix,
|
|
869
|
-
storedSlug,
|
|
870
|
-
nested: isNested,
|
|
871
|
-
homeSlug: "",
|
|
872
|
-
defaultLocale,
|
|
873
|
-
locales: activeLocales,
|
|
874
|
-
localePrefix: options.localePrefix,
|
|
875
|
-
queryAllLocaleSlugs: async (s, l) => {
|
|
876
|
-
const result = await queryAllLocaleSlugs({
|
|
877
|
-
collectionSlug,
|
|
878
|
-
slug: s,
|
|
879
|
-
slugField: "slug",
|
|
880
|
-
locale: l,
|
|
881
|
-
config: options.config
|
|
882
|
-
});
|
|
883
|
-
return result ?? undefined;
|
|
884
|
-
}
|
|
885
|
-
});
|
|
886
|
-
entries.push({
|
|
887
|
-
url,
|
|
888
|
-
lastModified: doc.updatedAt ? new Date(doc.updatedAt) : undefined,
|
|
889
|
-
changeFrequency: collectionDefaults.changefreq ?? "weekly",
|
|
890
|
-
priority: collectionDefaults.priority ?? 0.5,
|
|
891
|
-
alternates: { languages }
|
|
892
|
-
});
|
|
345
|
+
// src/createWWWConfig.ts
|
|
346
|
+
import { seoPlugin } from "@justanarthur/payload-plugin-seo";
|
|
347
|
+
import { imageHashPlugin } from "@justanarthur/payload-imagehash-plugin";
|
|
348
|
+
import { translator } from "@justanarthur/payload-plugin-translator";
|
|
349
|
+
function createWWWConfig() {
|
|
350
|
+
function withWWWConfig(input) {
|
|
351
|
+
const { defaultPluginsConfigs, ...config } = input;
|
|
352
|
+
const blocks = config.blocks || [];
|
|
353
|
+
const collections = mergeOrOverride([
|
|
354
|
+
createPagesCollection(blocks),
|
|
355
|
+
createPostsCollection()
|
|
356
|
+
], config.collections);
|
|
357
|
+
const globals = mergeOrOverride([
|
|
358
|
+
createHeaderGlobal(),
|
|
359
|
+
createFooterGlobal()
|
|
360
|
+
], config.globals);
|
|
361
|
+
const defaultPlugins = [
|
|
362
|
+
seoPlugin(mergeOrOverride({
|
|
363
|
+
collections: [PAGES_SLUG, POSTS_SLUG],
|
|
364
|
+
openaiApiKey: process.env.OPENAI_API_KEY,
|
|
365
|
+
autoGenerate: {
|
|
366
|
+
mode: "onCreateOrUpdate",
|
|
367
|
+
deriveFrom: "allScalars"
|
|
893
368
|
}
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
function createWWWConfig(options) {
|
|
902
|
-
const { locales, routing, blocks, linkRelationTo, registerPosts = true, nested = false, defaultPlugins } = options;
|
|
903
|
-
const defaultLocale = routing?.defaultLocale ?? locales[0] ?? "";
|
|
904
|
-
const localePrefixMode = (() => {
|
|
905
|
-
const raw = routing?.localePrefix;
|
|
906
|
-
if (typeof raw === "string")
|
|
907
|
-
return raw;
|
|
908
|
-
return raw?.mode ?? "always";
|
|
909
|
-
})();
|
|
910
|
-
if (locales.length === 0) {
|
|
911
|
-
throw new Error("createWWWConfig: `locales` must contain at least one entry.");
|
|
912
|
-
}
|
|
913
|
-
const buildPagesCollection = () => createPagesCollection(blocks, {
|
|
914
|
-
localePrefix: localePrefixMode,
|
|
915
|
-
defaultLocale,
|
|
916
|
-
nested
|
|
917
|
-
});
|
|
918
|
-
const buildPostsCollection = () => createPostsCollection({
|
|
919
|
-
localePrefix: localePrefixMode,
|
|
920
|
-
defaultLocale
|
|
921
|
-
});
|
|
922
|
-
const buildStaticPagesCollection = () => createStaticPagesCollection(blocks);
|
|
923
|
-
const buildHeaderGlobal = () => createHeaderGlobal({ linkRelationTo });
|
|
924
|
-
const buildFooterGlobal = () => createFooterGlobal({ linkRelationTo });
|
|
925
|
-
async function withWWWConfig(config) {
|
|
926
|
-
const baseDefaults = [
|
|
927
|
-
buildPagesCollection(),
|
|
928
|
-
buildStaticPagesCollection()
|
|
929
|
-
];
|
|
930
|
-
if (registerPosts)
|
|
931
|
-
baseDefaults.push(buildPostsCollection());
|
|
932
|
-
const defaultCollections = baseDefaults;
|
|
933
|
-
const collections = typeof config.collections === "function" ? config.collections({ defaultCollections }) : [...defaultCollections, ...config.collections || []];
|
|
934
|
-
const defaultGlobals = [buildHeaderGlobal(), buildFooterGlobal()];
|
|
935
|
-
const globals = typeof config.globals === "function" ? config.globals({ defaultGlobals }) : [...defaultGlobals, ...config.globals || []];
|
|
936
|
-
const renderDependencies = {
|
|
937
|
-
[PAGES_RENDER_PATH]: { path: PAGES_RENDER_PATH, type: "component" },
|
|
938
|
-
[POSTS_RENDER_PATH]: { path: POSTS_RENDER_PATH, type: "component" },
|
|
939
|
-
[HEADER_RENDER_PATH]: { path: HEADER_RENDER_PATH, type: "component" },
|
|
940
|
-
[FOOTER_RENDER_PATH]: { path: FOOTER_RENDER_PATH, type: "component" },
|
|
941
|
-
[LIVE_PREVIEW_LISTENER_PATH]: {
|
|
942
|
-
path: LIVE_PREVIEW_LISTENER_PATH,
|
|
943
|
-
type: "component"
|
|
944
|
-
}
|
|
945
|
-
};
|
|
946
|
-
for (const { slug, custom, admin } of blocks) {
|
|
947
|
-
const path = custom?.path ?? admin?.custom?.path;
|
|
948
|
-
if (typeof path === "string" && slug)
|
|
949
|
-
renderDependencies[slug] = { path, type: "component" };
|
|
950
|
-
}
|
|
951
|
-
for (const entry of [...collections, ...globals]) {
|
|
952
|
-
const path = entry.custom?.path;
|
|
953
|
-
if (typeof path === "string")
|
|
954
|
-
renderDependencies[path] = { path, type: "component" };
|
|
955
|
-
}
|
|
956
|
-
const [
|
|
957
|
-
{ seoPlugin },
|
|
958
|
-
{ imageHashPlugin },
|
|
959
|
-
{ translator }
|
|
960
|
-
] = await Promise.all([
|
|
961
|
-
import("@justanarthur/payload-plugin-seo"),
|
|
962
|
-
import("@justanarthur/payload-imagehash-plugin"),
|
|
963
|
-
import("@justanarthur/payload-plugin-translator")
|
|
964
|
-
]);
|
|
965
|
-
const defaultPluginList = [
|
|
966
|
-
seoPlugin({
|
|
967
|
-
collections: ["pages", "posts", "static-pages"],
|
|
968
|
-
autoGenerate: { mode: "onCreate", deriveFrom: "allScalars" }
|
|
969
|
-
}),
|
|
970
|
-
imageHashPlugin({ algorithm: "lqip-modern" }),
|
|
971
|
-
translator({
|
|
972
|
-
collections: ["pages", "posts", "static-pages"],
|
|
973
|
-
globals: ["header", "footer"],
|
|
369
|
+
}, defaultPluginsConfigs?.seo)),
|
|
370
|
+
imageHashPlugin(mergeOrOverride({
|
|
371
|
+
algorithm: "lqip-modern"
|
|
372
|
+
}, defaultPluginsConfigs?.imageHash)),
|
|
373
|
+
translator(mergeOrOverride({
|
|
374
|
+
collections: [PAGES_SLUG, POSTS_SLUG],
|
|
375
|
+
globals: [HEADER_SLUG, FOOTER_SLUG],
|
|
974
376
|
resolvers: [
|
|
975
377
|
openAIResolver({
|
|
976
378
|
apiKey: process.env.OPENAI_API_KEY,
|
|
977
379
|
chunkLength: 31,
|
|
978
|
-
model: "gpt-5-mini"
|
|
380
|
+
model: "gpt-5.4-mini"
|
|
979
381
|
})
|
|
980
382
|
]
|
|
981
|
-
})
|
|
383
|
+
}, defaultPluginsConfigs?.translator))
|
|
982
384
|
];
|
|
983
|
-
const
|
|
385
|
+
const plugins = mergeOrOverride(defaultPlugins, config.plugins);
|
|
984
386
|
return {
|
|
985
387
|
...config,
|
|
986
388
|
collections,
|
|
987
389
|
globals,
|
|
988
|
-
plugins
|
|
989
|
-
admin: {
|
|
990
|
-
...config.admin ?? {},
|
|
991
|
-
dependencies: {
|
|
992
|
-
...renderDependencies,
|
|
993
|
-
...config.admin?.dependencies ?? {}
|
|
994
|
-
}
|
|
995
|
-
}
|
|
390
|
+
plugins
|
|
996
391
|
};
|
|
997
392
|
}
|
|
998
393
|
return { withWWWConfig };
|
|
999
394
|
}
|
|
395
|
+
function mergeOrOverride(defaultValue, overrideValue) {
|
|
396
|
+
if (typeof overrideValue === "function")
|
|
397
|
+
return overrideValue(defaultValue);
|
|
398
|
+
if (overrideValue !== undefined)
|
|
399
|
+
return overrideValue;
|
|
400
|
+
return defaultValue;
|
|
401
|
+
}
|
|
1000
402
|
|
|
1001
403
|
// src/exports/config.ts
|
|
1002
404
|
var config_default = createWWWConfig;
|