@justanarthur/payload-www 0.1.1
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 +381 -0
- package/dist/access.d.ts +11 -0
- package/dist/access.js +34 -0
- package/dist/blocks.d.ts +24 -0
- package/dist/blocks.js +75 -0
- package/dist/collections.d.ts +200 -0
- package/dist/collections.js +625 -0
- package/dist/components.d.ts +6 -0
- package/dist/components.js +38 -0
- package/dist/config.d.ts +100 -0
- package/dist/config.js +914 -0
- package/dist/core-access.d.ts +11 -0
- package/dist/core-access.js +34 -0
- package/dist/core-blocks.d.ts +24 -0
- package/dist/core-blocks.js +75 -0
- package/dist/core-fields.d.ts +36 -0
- package/dist/core-fields.js +134 -0
- package/dist/core-utils.d.ts +16 -0
- package/dist/core-utils.js +59 -0
- package/dist/data-collections.d.ts +200 -0
- package/dist/data-collections.js +625 -0
- package/dist/data-seed.d.ts +76 -0
- package/dist/data-seed.js +212 -0
- package/dist/data-test.d.ts +30 -0
- package/dist/data-test.js +1018 -0
- package/dist/fields.d.ts +36 -0
- package/dist/fields.js +134 -0
- package/dist/globals.d.ts +48 -0
- package/dist/globals.js +228 -0
- package/dist/hooks.d.ts +108 -0
- package/dist/hooks.js +196 -0
- package/dist/imagehash.d.ts +3 -0
- package/dist/imagehash.js +24 -0
- package/dist/import-map-provider.d.ts +20 -0
- package/dist/import-map-provider.js +26 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +38 -0
- package/dist/metadata.d.ts +122 -0
- package/dist/metadata.js +335 -0
- package/dist/pages.d.ts +323 -0
- package/dist/pages.js +1016 -0
- package/dist/render-components.d.ts +42 -0
- package/dist/render-components.js +144 -0
- package/dist/render-metadata.d.ts +122 -0
- package/dist/render-metadata.js +335 -0
- package/dist/render-pages.d.ts +574 -0
- package/dist/render-pages.js +1450 -0
- package/dist/render-utils.d.ts +158 -0
- package/dist/render-utils.js +341 -0
- package/dist/seed.d.ts +76 -0
- package/dist/seed.js +212 -0
- package/dist/server.d.ts +922 -0
- package/dist/server.js +2055 -0
- package/dist/test.d.ts +30 -0
- package/dist/test.js +1018 -0
- package/dist/translator.d.ts +2 -0
- package/dist/translator.js +24 -0
- package/dist/utils.d.ts +16 -0
- package/dist/utils.js +59 -0
- package/dist/with-www-config.d.ts +100 -0
- package/dist/with-www-config.js +914 -0
- package/package.json +246 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
type LivePreviewListenerProps = {
|
|
3
|
+
serverURL?: string;
|
|
4
|
+
};
|
|
5
|
+
declare const LivePreviewListener: FC<LivePreviewListenerProps>;
|
|
6
|
+
import { FC as FC2 } from "react";
|
|
7
|
+
type AdminBarLabels = {
|
|
8
|
+
/** Trigger button label (when popover is closed). */
|
|
9
|
+
trigger?: string;
|
|
10
|
+
/** Exit-preview link label. */
|
|
11
|
+
exitPreview?: string;
|
|
12
|
+
/** Tooltip / a11y description for the trigger button. */
|
|
13
|
+
triggerHint?: string;
|
|
14
|
+
};
|
|
15
|
+
type AdminBarProps = {
|
|
16
|
+
/**
|
|
17
|
+
* Whether draft mode is currently active. When `false`, the
|
|
18
|
+
* component renders `null` — zero DOM cost in production.
|
|
19
|
+
*/
|
|
20
|
+
preview: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Path to navigate to when the host clicks "Exit preview". Defaults
|
|
23
|
+
* to `/next/exit-preview` (matches Payload's standard handler).
|
|
24
|
+
*/
|
|
25
|
+
exitPreviewPath?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Per-label overrides for i18n hosts. Defaults are English.
|
|
28
|
+
*/
|
|
29
|
+
labels?: AdminBarLabels;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Next.js App Router–style draft-mode admin bar. Renders only when
|
|
33
|
+
* `preview` is true; shows a small floating button in the bottom-right
|
|
34
|
+
* that opens a native `<dialog>` popover with an "Exit preview" link.
|
|
35
|
+
*
|
|
36
|
+
* Mirrors `LivePreviewListener` as a self-contained `'use client'`
|
|
37
|
+
* component the host drops into the layout's providers tree. No
|
|
38
|
+
* dependency on `@payloadcms/admin-bar` — pure React + a few
|
|
39
|
+
* Tailwind-free inline styles so hosts can theme freely.
|
|
40
|
+
*/
|
|
41
|
+
declare const AdminBar: FC2<AdminBarProps>;
|
|
42
|
+
export { LivePreviewListener as default, LivePreviewListenerProps, LivePreviewListener, AdminBarProps, AdminBarLabels, AdminBar };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __returnValue = (v) => v;
|
|
5
|
+
function __exportSetter(name, newValue) {
|
|
6
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
7
|
+
}
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
set: __exportSetter.bind(all, name)
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
18
|
+
|
|
19
|
+
// src/render/components/LivePreviewListener.tsx
|
|
20
|
+
import { RefreshRouteOnSave as PayloadLivePreview } from "@payloadcms/live-preview-react";
|
|
21
|
+
import { useRouter } from "next/navigation";
|
|
22
|
+
import { jsx } from "react/jsx-runtime";
|
|
23
|
+
|
|
24
|
+
var LivePreviewListener = ({ serverURL }) => {
|
|
25
|
+
const router = useRouter();
|
|
26
|
+
const url = serverURL ?? process.env.NEXT_PUBLIC_SERVER_URL ?? (typeof window !== "undefined" ? window.location.origin : "");
|
|
27
|
+
return /* @__PURE__ */ jsx(PayloadLivePreview, {
|
|
28
|
+
refresh: router.refresh,
|
|
29
|
+
serverURL: url
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// src/render/components/AdminBar.tsx
|
|
34
|
+
import { useRouter as useRouter2 } from "next/navigation";
|
|
35
|
+
import { useState } from "react";
|
|
36
|
+
import { jsx as jsx2, jsxs, Fragment } from "react/jsx-runtime";
|
|
37
|
+
|
|
38
|
+
var defaultLabels = {
|
|
39
|
+
trigger: "Preview",
|
|
40
|
+
exitPreview: "Exit preview",
|
|
41
|
+
triggerHint: "Open draft-mode admin bar"
|
|
42
|
+
};
|
|
43
|
+
var AdminBar = ({ preview, exitPreviewPath = "/next/exit-preview", labels }) => {
|
|
44
|
+
const router = useRouter2();
|
|
45
|
+
const [open, setOpen] = useState(false);
|
|
46
|
+
const merged = { ...defaultLabels, ...labels };
|
|
47
|
+
if (!preview)
|
|
48
|
+
return null;
|
|
49
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ jsx2("button", {
|
|
52
|
+
type: "button",
|
|
53
|
+
onClick: () => setOpen(true),
|
|
54
|
+
title: merged.triggerHint,
|
|
55
|
+
style: {
|
|
56
|
+
position: "fixed",
|
|
57
|
+
bottom: 16,
|
|
58
|
+
right: 16,
|
|
59
|
+
zIndex: 2147483647,
|
|
60
|
+
padding: "8px 14px",
|
|
61
|
+
borderRadius: 9999,
|
|
62
|
+
border: "1px solid rgba(0,0,0,0.12)",
|
|
63
|
+
background: "#111",
|
|
64
|
+
color: "#fff",
|
|
65
|
+
fontSize: 12,
|
|
66
|
+
fontWeight: 600,
|
|
67
|
+
letterSpacing: 0.4,
|
|
68
|
+
textTransform: "uppercase",
|
|
69
|
+
cursor: "pointer",
|
|
70
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.18)"
|
|
71
|
+
},
|
|
72
|
+
children: merged.trigger
|
|
73
|
+
}),
|
|
74
|
+
/* @__PURE__ */ jsx2("dialog", {
|
|
75
|
+
open,
|
|
76
|
+
onClose: () => setOpen(false),
|
|
77
|
+
onClick: (e) => {
|
|
78
|
+
if (e.target === e.currentTarget)
|
|
79
|
+
setOpen(false);
|
|
80
|
+
},
|
|
81
|
+
style: {
|
|
82
|
+
position: "fixed",
|
|
83
|
+
inset: 0,
|
|
84
|
+
width: "100vw",
|
|
85
|
+
height: "100vh",
|
|
86
|
+
maxWidth: "100vw",
|
|
87
|
+
maxHeight: "100vh",
|
|
88
|
+
margin: 0,
|
|
89
|
+
padding: 0,
|
|
90
|
+
border: "none",
|
|
91
|
+
background: "rgba(0,0,0,0.32)",
|
|
92
|
+
zIndex: 2147483647
|
|
93
|
+
},
|
|
94
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
95
|
+
style: {
|
|
96
|
+
position: "absolute",
|
|
97
|
+
bottom: 24,
|
|
98
|
+
right: 24,
|
|
99
|
+
minWidth: 220,
|
|
100
|
+
padding: 16,
|
|
101
|
+
borderRadius: 8,
|
|
102
|
+
background: "#fff",
|
|
103
|
+
color: "#111",
|
|
104
|
+
boxShadow: "0 12px 36px rgba(0,0,0,0.24)"
|
|
105
|
+
},
|
|
106
|
+
onClick: (e) => e.stopPropagation(),
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ jsx2("div", {
|
|
109
|
+
style: { fontSize: 13, fontWeight: 600, marginBottom: 8 },
|
|
110
|
+
children: merged.trigger
|
|
111
|
+
}),
|
|
112
|
+
/* @__PURE__ */ jsx2("div", {
|
|
113
|
+
style: { fontSize: 12, color: "#666", marginBottom: 12 },
|
|
114
|
+
children: "Draft mode is on. Edits in Payload will refresh this view automatically."
|
|
115
|
+
}),
|
|
116
|
+
/* @__PURE__ */ jsx2("a", {
|
|
117
|
+
href: exitPreviewPath,
|
|
118
|
+
onClick: () => router.refresh(),
|
|
119
|
+
style: {
|
|
120
|
+
display: "inline-block",
|
|
121
|
+
padding: "6px 10px",
|
|
122
|
+
borderRadius: 6,
|
|
123
|
+
background: "#111",
|
|
124
|
+
color: "#fff",
|
|
125
|
+
fontSize: 12,
|
|
126
|
+
fontWeight: 600,
|
|
127
|
+
textDecoration: "none"
|
|
128
|
+
},
|
|
129
|
+
children: merged.exitPreview
|
|
130
|
+
})
|
|
131
|
+
]
|
|
132
|
+
})
|
|
133
|
+
})
|
|
134
|
+
]
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// src/exports/render-components.ts
|
|
139
|
+
var render_components_default = LivePreviewListener;
|
|
140
|
+
export {
|
|
141
|
+
render_components_default as default,
|
|
142
|
+
LivePreviewListener,
|
|
143
|
+
AdminBar
|
|
144
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
type ArticleLdOptions = {
|
|
2
|
+
doc: Record<string, any>;
|
|
3
|
+
url: string;
|
|
4
|
+
locale: string;
|
|
5
|
+
siteUrl: string;
|
|
6
|
+
type?: "BlogPosting" | "Article" | "NewsArticle" | "TechArticle";
|
|
7
|
+
publisherName?: string;
|
|
8
|
+
publisherLogo?: string | null;
|
|
9
|
+
};
|
|
10
|
+
declare function buildArticleLd({ doc, url, locale, siteUrl, type, publisherName, publisherLogo }: ArticleLdOptions): Record<string, unknown>;
|
|
11
|
+
type BreadcrumbItem = {
|
|
12
|
+
label: string;
|
|
13
|
+
url: string;
|
|
14
|
+
};
|
|
15
|
+
declare function buildBreadcrumbsLd({ items, currentUrl }: {
|
|
16
|
+
items: BreadcrumbItem[];
|
|
17
|
+
currentUrl: string;
|
|
18
|
+
}): Record<string, unknown>;
|
|
19
|
+
declare function buildOrganizationLd({ siteUrl, name, logo, sameAs }: {
|
|
20
|
+
siteUrl: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
logo?: string;
|
|
23
|
+
sameAs?: string[];
|
|
24
|
+
}): Record<string, unknown>;
|
|
25
|
+
declare function buildHreflangAlternates<L extends string>({ siteUrl, locale, urlPrefix, storedSlug, queryAllLocaleSlugs, nested, homeSlug, defaultLocale, locales, localePrefix }: {
|
|
26
|
+
siteUrl: string;
|
|
27
|
+
locale: L;
|
|
28
|
+
urlPrefix: string;
|
|
29
|
+
storedSlug: string;
|
|
30
|
+
queryAllLocaleSlugs: (slug: string, locale: L) => Promise<Partial<Record<L, string>> | undefined>;
|
|
31
|
+
nested: boolean;
|
|
32
|
+
homeSlug: string;
|
|
33
|
+
defaultLocale: L;
|
|
34
|
+
locales: readonly L[];
|
|
35
|
+
/**
|
|
36
|
+
* Locale prefix mode — mirrors next-intl's `localePrefix` so each
|
|
37
|
+
* alternate URL matches the host's actual route shape:
|
|
38
|
+
*
|
|
39
|
+
* - `'always'`: every URL is prefixed with `/{locale}/…`
|
|
40
|
+
* (e.g. `/en/about`, `/uk/about`). The default — preserves
|
|
41
|
+
* the helper's prior behavior.
|
|
42
|
+
* - `'as-needed'`: the default locale renders without a prefix
|
|
43
|
+
* (e.g. `/about`), other locales are prefixed (`/uk/about`).
|
|
44
|
+
* Critical: callers that emit hreflang alongside a canonical
|
|
45
|
+
* URL built with `as-needed` mode MUST pass this through,
|
|
46
|
+
* otherwise the `en` and `x-default` alternates point to URLs
|
|
47
|
+
* the host doesn't actually serve.
|
|
48
|
+
* - `'never'`: no locale prefix at all.
|
|
49
|
+
*/
|
|
50
|
+
localePrefix?: "always" | "as-needed" | "never";
|
|
51
|
+
}): Promise<Record<string, string>>;
|
|
52
|
+
declare function segmentsToStoredSlug(segments: string[] | string, nested?: boolean): string;
|
|
53
|
+
declare function segmentsToUrlPath(segments: string[] | string, nested?: boolean): string;
|
|
54
|
+
declare function storedSlugToSegments(storedSlug: string, nested?: boolean): string[] | string;
|
|
55
|
+
declare function buildCanonicalUrl<L extends string>({ siteUrl, locale, urlPrefix, urlPath }: {
|
|
56
|
+
siteUrl: string;
|
|
57
|
+
locale: L;
|
|
58
|
+
urlPrefix: string;
|
|
59
|
+
urlPath: string;
|
|
60
|
+
}): string;
|
|
61
|
+
declare function getUrlPath(segments: string[] | string, nested: boolean, homeSlug: string): string;
|
|
62
|
+
import { DataFromCollectionSlug, ImportMap, SanitizedConfig } from "payload";
|
|
63
|
+
declare const queryDocBySlug: <S extends string>({ collectionSlug, slug, slugField, locale, draft, config }: {
|
|
64
|
+
collectionSlug: S;
|
|
65
|
+
slug: string;
|
|
66
|
+
slugField?: string;
|
|
67
|
+
locale: string;
|
|
68
|
+
draft?: boolean;
|
|
69
|
+
config: Promise<SanitizedConfig>;
|
|
70
|
+
}) => Promise<DataFromCollectionSlug<S> | null>;
|
|
71
|
+
declare const queryAllDocs: <S extends string>({ collectionSlug, slugField, locale, config }: {
|
|
72
|
+
collectionSlug: S;
|
|
73
|
+
slugField?: string;
|
|
74
|
+
locale: string;
|
|
75
|
+
config: Promise<SanitizedConfig>;
|
|
76
|
+
}) => Promise<DataFromCollectionSlug<S>[]>;
|
|
77
|
+
declare const queryAllLocaleSlugs2: <S extends string>({ collectionSlug, slug, slugField, locale, config }: {
|
|
78
|
+
collectionSlug: S;
|
|
79
|
+
slug: string;
|
|
80
|
+
slugField?: string;
|
|
81
|
+
locale: string;
|
|
82
|
+
config: Promise<SanitizedConfig>;
|
|
83
|
+
}) => Promise<Record<string, string> | undefined>;
|
|
84
|
+
declare function getRenderModuleExports(exportName: string, collection: {
|
|
85
|
+
custom?: Record<string, unknown>;
|
|
86
|
+
} | undefined, importMap: ImportMap): unknown;
|
|
87
|
+
import { SanitizedConfig as SanitizedConfig_ee8ogz } from "payload";
|
|
88
|
+
import { DataFromCollectionSlug as DataFromCollectionSlug_2e2bqb } from "payload";
|
|
89
|
+
declare const _default: {
|
|
90
|
+
buildArticleLd: typeof buildArticleLd;
|
|
91
|
+
buildBreadcrumbsLd: typeof buildBreadcrumbsLd;
|
|
92
|
+
buildOrganizationLd: typeof buildOrganizationLd;
|
|
93
|
+
buildHreflangAlternates: typeof buildHreflangAlternates;
|
|
94
|
+
queryDocBySlug: <S extends string>({ collectionSlug, slug, slugField, locale, draft, config }: {
|
|
95
|
+
collectionSlug: S;
|
|
96
|
+
slug: string;
|
|
97
|
+
slugField?: string;
|
|
98
|
+
locale: string;
|
|
99
|
+
draft?: boolean;
|
|
100
|
+
config: Promise<SanitizedConfig_ee8ogz>;
|
|
101
|
+
}) => Promise<DataFromCollectionSlug_2e2bqb<S> | null>;
|
|
102
|
+
queryAllDocs: <S extends string>({ collectionSlug, slugField, locale, config }: {
|
|
103
|
+
collectionSlug: S;
|
|
104
|
+
slugField?: string;
|
|
105
|
+
locale: string;
|
|
106
|
+
config: Promise<SanitizedConfig_ee8ogz>;
|
|
107
|
+
}) => Promise<DataFromCollectionSlug_2e2bqb<S>[]>;
|
|
108
|
+
queryAllLocaleSlugs2: <S extends string>({ collectionSlug, slug, slugField, locale, config }: {
|
|
109
|
+
collectionSlug: S;
|
|
110
|
+
slug: string;
|
|
111
|
+
slugField?: string;
|
|
112
|
+
locale: string;
|
|
113
|
+
config: Promise<SanitizedConfig_ee8ogz>;
|
|
114
|
+
}) => Promise<Record<string, string> | undefined>;
|
|
115
|
+
getUrlPath: typeof getUrlPath;
|
|
116
|
+
segmentsToStoredSlug: typeof segmentsToStoredSlug;
|
|
117
|
+
segmentsToUrlPath: typeof segmentsToUrlPath;
|
|
118
|
+
storedSlugToSegments: typeof storedSlugToSegments;
|
|
119
|
+
buildCanonicalUrl: typeof buildCanonicalUrl;
|
|
120
|
+
getRenderModuleExports: typeof getRenderModuleExports;
|
|
121
|
+
};
|
|
122
|
+
export { storedSlugToSegments, segmentsToUrlPath, segmentsToStoredSlug, queryDocBySlug, queryAllLocaleSlugs2 as queryAllLocaleSlugs, queryAllDocs, getUrlPath, getRenderModuleExports, _default as default, buildOrganizationLd, buildHreflangAlternates, buildCanonicalUrl, buildBreadcrumbsLd, buildArticleLd, BreadcrumbItem, ArticleLdOptions };
|
|
@@ -0,0 +1,335 @@
|
|
|
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
|
+
|
|
18
|
+
// src/render/metadata/jsonld.ts
|
|
19
|
+
function getImageUrl(doc, siteUrl) {
|
|
20
|
+
const img = doc?.meta?.image ?? doc?.heroImage ?? doc?.image;
|
|
21
|
+
if (!img)
|
|
22
|
+
return null;
|
|
23
|
+
if (typeof img === "string")
|
|
24
|
+
return img;
|
|
25
|
+
if (img?.url)
|
|
26
|
+
return img.url.startsWith("http") ? img.url : `${siteUrl}${img.url}`;
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
function resolveLocalizedField(value, locale) {
|
|
30
|
+
if (value == null)
|
|
31
|
+
return "";
|
|
32
|
+
if (typeof value === "string") {
|
|
33
|
+
if (!value.startsWith("{"))
|
|
34
|
+
return value;
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(value);
|
|
37
|
+
return resolveLocalizedField(parsed, locale);
|
|
38
|
+
} catch {
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (typeof value !== "object")
|
|
43
|
+
return "";
|
|
44
|
+
const obj = value;
|
|
45
|
+
if (typeof obj[locale] === "string" && obj[locale].length > 0) {
|
|
46
|
+
return obj[locale];
|
|
47
|
+
}
|
|
48
|
+
return Object.values(obj).filter((v) => typeof v === "string" && v.length > 0).join(" / ");
|
|
49
|
+
}
|
|
50
|
+
function buildArticleLd({
|
|
51
|
+
doc,
|
|
52
|
+
url,
|
|
53
|
+
locale,
|
|
54
|
+
siteUrl,
|
|
55
|
+
type = "BlogPosting",
|
|
56
|
+
publisherName,
|
|
57
|
+
publisherLogo
|
|
58
|
+
}) {
|
|
59
|
+
const name = publisherName ?? new URL(siteUrl).hostname;
|
|
60
|
+
const ld = {
|
|
61
|
+
"@context": "https://schema.org",
|
|
62
|
+
"@type": type,
|
|
63
|
+
"@id": `${url}#article`,
|
|
64
|
+
headline: resolveLocalizedField(doc.title, locale),
|
|
65
|
+
description: resolveLocalizedField(doc.meta?.description ?? doc.description ?? doc.excerpt, locale),
|
|
66
|
+
inLanguage: locale,
|
|
67
|
+
url,
|
|
68
|
+
dateModified: doc.updatedAt ? new Date(doc.updatedAt).toISOString() : undefined
|
|
69
|
+
};
|
|
70
|
+
const datePublished = doc.publishedAt ?? doc.createdAt;
|
|
71
|
+
if (datePublished)
|
|
72
|
+
ld.datePublished = new Date(datePublished).toISOString();
|
|
73
|
+
const imgUrl = getImageUrl(doc, siteUrl);
|
|
74
|
+
if (imgUrl)
|
|
75
|
+
ld.image = imgUrl;
|
|
76
|
+
ld.author = { "@type": "Organization", name, url: siteUrl };
|
|
77
|
+
const publisher = { "@type": "Organization", name };
|
|
78
|
+
if (publisherLogo !== undefined) {
|
|
79
|
+
if (publisherLogo !== null)
|
|
80
|
+
publisher.logo = { "@type": "ImageObject", url: publisherLogo };
|
|
81
|
+
}
|
|
82
|
+
ld.publisher = publisher;
|
|
83
|
+
return ld;
|
|
84
|
+
}
|
|
85
|
+
function buildBreadcrumbsLd({
|
|
86
|
+
items,
|
|
87
|
+
currentUrl
|
|
88
|
+
}) {
|
|
89
|
+
return {
|
|
90
|
+
"@context": "https://schema.org",
|
|
91
|
+
"@type": "BreadcrumbList",
|
|
92
|
+
itemListElement: items.map((item, index) => ({
|
|
93
|
+
"@type": "ListItem",
|
|
94
|
+
position: index + 1,
|
|
95
|
+
name: item.label,
|
|
96
|
+
item: index === items.length - 1 ? currentUrl : item.url
|
|
97
|
+
}))
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function buildOrganizationLd({
|
|
101
|
+
siteUrl,
|
|
102
|
+
name,
|
|
103
|
+
logo,
|
|
104
|
+
sameAs
|
|
105
|
+
}) {
|
|
106
|
+
const org = {
|
|
107
|
+
"@context": "https://schema.org",
|
|
108
|
+
"@type": "Organization",
|
|
109
|
+
"@id": `${siteUrl}#organization`,
|
|
110
|
+
url: siteUrl,
|
|
111
|
+
...name && { name },
|
|
112
|
+
...logo && { logo: { "@type": "ImageObject", url: logo } },
|
|
113
|
+
...sameAs && sameAs.length > 0 && { sameAs }
|
|
114
|
+
};
|
|
115
|
+
return org;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/render/metadata/hreflang.ts
|
|
119
|
+
async function buildHreflangAlternates({
|
|
120
|
+
siteUrl,
|
|
121
|
+
locale,
|
|
122
|
+
urlPrefix,
|
|
123
|
+
storedSlug,
|
|
124
|
+
queryAllLocaleSlugs,
|
|
125
|
+
nested,
|
|
126
|
+
homeSlug,
|
|
127
|
+
defaultLocale,
|
|
128
|
+
locales,
|
|
129
|
+
localePrefix = "always"
|
|
130
|
+
}) {
|
|
131
|
+
const allLocaleSlugs = await queryAllLocaleSlugs(storedSlug, locale);
|
|
132
|
+
const languages = {};
|
|
133
|
+
const urlFor = (l, slug) => {
|
|
134
|
+
const trimmedPrefix = urlPrefix.replace(/^\/|\/$/g, "");
|
|
135
|
+
const prefixSegment = trimmedPrefix ? `/${trimmedPrefix}` : "";
|
|
136
|
+
const urlPath = slug === homeSlug ? "/" : nested ? "/" + slug.replaceAll("_", "/") : "/" + slug;
|
|
137
|
+
const localeSegment = localePrefix === "never" ? "" : localePrefix === "as-needed" && l === defaultLocale ? "" : `/${l}`;
|
|
138
|
+
return `${siteUrl}${localeSegment}${prefixSegment}${urlPath}`;
|
|
139
|
+
};
|
|
140
|
+
for (const l of locales) {
|
|
141
|
+
const slugForLocale = allLocaleSlugs?.[l];
|
|
142
|
+
if (!slugForLocale)
|
|
143
|
+
continue;
|
|
144
|
+
languages[l] = urlFor(l, slugForLocale);
|
|
145
|
+
}
|
|
146
|
+
if (allLocaleSlugs?.[defaultLocale]) {
|
|
147
|
+
languages["x-default"] = urlFor(defaultLocale, allLocaleSlugs[defaultLocale]);
|
|
148
|
+
}
|
|
149
|
+
return languages;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/render/metadata/slug.ts
|
|
153
|
+
var SLUG_NESTED_DIVIDER = "_";
|
|
154
|
+
function segmentsToStoredSlug(segments, nested) {
|
|
155
|
+
if (!Array.isArray(segments))
|
|
156
|
+
return segments;
|
|
157
|
+
if (nested)
|
|
158
|
+
return segments.join(SLUG_NESTED_DIVIDER);
|
|
159
|
+
return segments[0] ?? "";
|
|
160
|
+
}
|
|
161
|
+
function segmentsToUrlPath(segments, nested) {
|
|
162
|
+
if (!Array.isArray(segments))
|
|
163
|
+
return "/" + segments;
|
|
164
|
+
if (nested)
|
|
165
|
+
return "/" + segments.join("/");
|
|
166
|
+
return "/" + (segments[0] ?? "");
|
|
167
|
+
}
|
|
168
|
+
function storedSlugToSegments(storedSlug, nested) {
|
|
169
|
+
if (nested)
|
|
170
|
+
return storedSlug.split(SLUG_NESTED_DIVIDER);
|
|
171
|
+
return storedSlug;
|
|
172
|
+
}
|
|
173
|
+
function buildCanonicalUrl({
|
|
174
|
+
siteUrl,
|
|
175
|
+
locale,
|
|
176
|
+
urlPrefix,
|
|
177
|
+
urlPath
|
|
178
|
+
}) {
|
|
179
|
+
const trimmedPrefix = urlPrefix.replace(/^\/|\/$/g, "");
|
|
180
|
+
const prefixSegment = trimmedPrefix ? `/${trimmedPrefix}` : "";
|
|
181
|
+
return `${siteUrl}/${locale}${prefixSegment}${urlPath}`;
|
|
182
|
+
}
|
|
183
|
+
function getUrlPath(segments, nested, homeSlug) {
|
|
184
|
+
const urlPath = segmentsToUrlPath(segments, nested);
|
|
185
|
+
if (nested && !Array.isArray(segments)) {
|
|
186
|
+
if (segments === homeSlug)
|
|
187
|
+
return "/";
|
|
188
|
+
} else if (nested && Array.isArray(segments)) {
|
|
189
|
+
const stored = segments.join(SLUG_NESTED_DIVIDER);
|
|
190
|
+
if (stored === homeSlug)
|
|
191
|
+
return "/";
|
|
192
|
+
}
|
|
193
|
+
return urlPath;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// src/render/metadata/query.ts
|
|
197
|
+
import { getPayload } from "payload";
|
|
198
|
+
import { cache } from "react";
|
|
199
|
+
|
|
200
|
+
// src/core/utils/getFromImportMap.ts
|
|
201
|
+
function getFromImportMap(key, importMap) {
|
|
202
|
+
return importMap[key.includes("#") ? key : key + "#default"];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// src/render/metadata/query.ts
|
|
206
|
+
var queryDocBySlug = cache(async function queryDocBySlug2({
|
|
207
|
+
collectionSlug,
|
|
208
|
+
slug,
|
|
209
|
+
slugField = "slug",
|
|
210
|
+
locale,
|
|
211
|
+
draft = false,
|
|
212
|
+
config
|
|
213
|
+
}) {
|
|
214
|
+
const payload = await getPayload({ config });
|
|
215
|
+
const result = await payload.find({
|
|
216
|
+
collection: collectionSlug,
|
|
217
|
+
draft,
|
|
218
|
+
limit: 1,
|
|
219
|
+
pagination: false,
|
|
220
|
+
overrideAccess: draft,
|
|
221
|
+
where: { [slugField]: { equals: slug } },
|
|
222
|
+
locale
|
|
223
|
+
});
|
|
224
|
+
return result.docs?.[0] ?? null;
|
|
225
|
+
});
|
|
226
|
+
var queryAllDocs = cache(async function queryAllDocs2({
|
|
227
|
+
collectionSlug,
|
|
228
|
+
slugField = "slug",
|
|
229
|
+
locale,
|
|
230
|
+
config
|
|
231
|
+
}) {
|
|
232
|
+
const payload = await getPayload({ config });
|
|
233
|
+
const result = await payload.find({
|
|
234
|
+
collection: collectionSlug,
|
|
235
|
+
draft: false,
|
|
236
|
+
limit: 1000,
|
|
237
|
+
pagination: false,
|
|
238
|
+
overrideAccess: false,
|
|
239
|
+
select: { [slugField]: true },
|
|
240
|
+
locale
|
|
241
|
+
});
|
|
242
|
+
return result.docs ?? [];
|
|
243
|
+
});
|
|
244
|
+
var queryAllLocaleSlugs = cache(async function queryAllLocaleSlugs2({
|
|
245
|
+
collectionSlug,
|
|
246
|
+
slug,
|
|
247
|
+
slugField = "slug",
|
|
248
|
+
locale,
|
|
249
|
+
config
|
|
250
|
+
}) {
|
|
251
|
+
const payload = await getPayload({ config });
|
|
252
|
+
const result = await payload.find({
|
|
253
|
+
collection: collectionSlug,
|
|
254
|
+
draft: false,
|
|
255
|
+
limit: 1,
|
|
256
|
+
pagination: false,
|
|
257
|
+
overrideAccess: false,
|
|
258
|
+
locale,
|
|
259
|
+
where: { [slugField]: { equals: slug } },
|
|
260
|
+
select: { [slugField]: true }
|
|
261
|
+
});
|
|
262
|
+
const doc = result.docs?.[0];
|
|
263
|
+
if (!doc)
|
|
264
|
+
return;
|
|
265
|
+
const fieldValue = doc?.[slugField];
|
|
266
|
+
if (fieldValue && typeof fieldValue === "object") {
|
|
267
|
+
return fieldValue;
|
|
268
|
+
}
|
|
269
|
+
const resolved = await config;
|
|
270
|
+
const rawLocales = Array.isArray(resolved?.localization?.localeCodes) ? resolved.localization.localeCodes : resolved?.localization?.locales?.map((l) => l.code) ?? [];
|
|
271
|
+
const out = {};
|
|
272
|
+
for (const l of rawLocales)
|
|
273
|
+
out[l] = String(fieldValue ?? slug);
|
|
274
|
+
return out;
|
|
275
|
+
});
|
|
276
|
+
var queryGlobal = cache(async function queryGlobal2({
|
|
277
|
+
globalSlug,
|
|
278
|
+
locale,
|
|
279
|
+
depth = 0,
|
|
280
|
+
draft = false,
|
|
281
|
+
config
|
|
282
|
+
}) {
|
|
283
|
+
const payload = await getPayload({ config });
|
|
284
|
+
try {
|
|
285
|
+
const global = await payload.findGlobal({
|
|
286
|
+
slug: globalSlug,
|
|
287
|
+
depth,
|
|
288
|
+
draft,
|
|
289
|
+
locale
|
|
290
|
+
});
|
|
291
|
+
return global;
|
|
292
|
+
} catch {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
function getRenderModuleExports(exportName, collection, importMap) {
|
|
297
|
+
const path = collection?.custom?.path;
|
|
298
|
+
if (!path)
|
|
299
|
+
return;
|
|
300
|
+
const mod = getFromImportMap(path, importMap);
|
|
301
|
+
return mod?.[exportName];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/exports/render-metadata.ts
|
|
305
|
+
var render_metadata_default = {
|
|
306
|
+
buildArticleLd,
|
|
307
|
+
buildBreadcrumbsLd,
|
|
308
|
+
buildOrganizationLd,
|
|
309
|
+
buildHreflangAlternates,
|
|
310
|
+
queryDocBySlug,
|
|
311
|
+
queryAllDocs,
|
|
312
|
+
queryAllLocaleSlugs,
|
|
313
|
+
getUrlPath,
|
|
314
|
+
segmentsToStoredSlug,
|
|
315
|
+
segmentsToUrlPath,
|
|
316
|
+
storedSlugToSegments,
|
|
317
|
+
buildCanonicalUrl,
|
|
318
|
+
getRenderModuleExports
|
|
319
|
+
};
|
|
320
|
+
export {
|
|
321
|
+
storedSlugToSegments,
|
|
322
|
+
segmentsToUrlPath,
|
|
323
|
+
segmentsToStoredSlug,
|
|
324
|
+
queryDocBySlug,
|
|
325
|
+
queryAllLocaleSlugs,
|
|
326
|
+
queryAllDocs,
|
|
327
|
+
getUrlPath,
|
|
328
|
+
getRenderModuleExports,
|
|
329
|
+
render_metadata_default as default,
|
|
330
|
+
buildOrganizationLd,
|
|
331
|
+
buildHreflangAlternates,
|
|
332
|
+
buildCanonicalUrl,
|
|
333
|
+
buildBreadcrumbsLd,
|
|
334
|
+
buildArticleLd
|
|
335
|
+
};
|