@bison-lab/payload-core 3.17.0 → 3.19.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 +71 -14
- package/dist/admin.d.mts +41 -4
- package/dist/admin.d.mts.map +1 -1
- package/dist/admin.mjs +265 -8
- package/dist/admin.mjs.map +1 -1
- package/dist/index.d.mts +113 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +447 -9
- package/dist/index.mjs.map +1 -1
- package/dist/{looks-Dk0l0mif.d.mts → looks-CQ_DiSQO.d.mts} +1 -1
- package/dist/{looks-Dk0l0mif.d.mts.map → looks-CQ_DiSQO.d.mts.map} +1 -1
- package/dist/metadata.d.mts +1 -1
- package/dist/navigation.d.mts +2 -0
- package/dist/navigation.mjs +2 -0
- package/dist/published-ByS86dhW.mjs +43 -0
- package/dist/published-ByS86dhW.mjs.map +1 -0
- package/dist/published-C49gmzAL.d.mts +68 -0
- package/dist/published-C49gmzAL.d.mts.map +1 -0
- package/dist/theme.d.mts +1 -1
- package/dist/{title-B2-gWQZd.d.mts → title-sWwcCqHT.d.mts} +1 -1
- package/dist/{title-B2-gWQZd.d.mts.map → title-sWwcCqHT.d.mts.map} +1 -1
- package/package.json +5 -1
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { n as documentTitle, r as titleTemplate, t as SHARE_IMAGE_SIZE } from "./share-image-C4ILz4p2.mjs";
|
|
2
2
|
import { A as THEME_FONT_FIELD, C as validateThemeHex, D as THEME_COLOR_SCALE_FIELD, E as THEME_COLOR_FIELD, F as THEME_PUBLISH_FIELD, I as THEME_SAVE_BUTTON, L as THEME_SECTION_HEADING, M as THEME_IDENTITY_FALLBACK, N as THEME_LIBRARY_FIELD, O as THEME_CONTRAST_REPORT, P as THEME_PAIRING_FIELD, R as headingSelectValue, S as validateSourceIncluded, T as THEME_APPEARANCE_FIELD, _ as THEME_SLUG, a as pageEditorLooks, c as findColorTokens, d as rewriteColorToken, f as themeColorKeys, g as THEME_IDENTITY_SLUG, h as THEME_COLORS_SLUG, i as PAGE_EDITOR_SYSTEM_KEYS, j as THEME_GREY_SCALE_FIELD, k as THEME_DOCUMENT_CONTROLS, l as rewriteColorTokens, m as THEME_APPEARANCE_SLUG, n as colorTokenField, o as pageEditorTokens, p as SYSTEM_COLOR_KEYS, r as lookField, s as themeLibraryFromDoc, t as resolveThemeIdentity, u as deleteLibraryColor, v as THEME_TYPOGRAPHY_SLUG, w as LOOK_FIELD, x as themeConfigFromDoc, y as docFromConfig } from "./identity-LAzSeorC.mjs";
|
|
3
|
+
import { a as NAVIGATION_FOOTER_SLUG, i as NAVIGATION_FOOTER_DB_NAME, n as NAVIGATION_DB_NAME, o as NAVIGATION_SLUG, r as NAVIGATION_FEATURE, t as getNavigation } from "./published-ByS86dhW.mjs";
|
|
3
4
|
import { seoPlugin as seoPlugin$1 } from "@payloadcms/plugin-seo";
|
|
4
5
|
import { catalog } from "@bison-lab/fonts";
|
|
5
6
|
import { DESTRUCTIVE_SCALE_HEX, SHADE_STEPS, presetHints } from "@bison-lab/tokens";
|
|
6
|
-
import { APIError, ValidationError, definePlugin, validations } from "payload";
|
|
7
|
+
import { APIError, Forbidden, ValidationError, definePlugin, validations } from "payload";
|
|
7
8
|
import { select, text } from "payload/shared";
|
|
8
9
|
//#region src/seo/fields.ts
|
|
9
10
|
/**
|
|
@@ -623,7 +624,7 @@ const DEFAULT_ROLE_MATRIX = ROLES.map((role) => ({
|
|
|
623
624
|
}));
|
|
624
625
|
const DEVELOPER_DESCRIPTION = "Everything, including features not released for assignment.";
|
|
625
626
|
const LAST_USERS_TICK_MESSAGE = "Keep Users granted on at least one of Admin or Developer.";
|
|
626
|
-
const MISSING_SEED_ROLES_MESSAGE = "Roles must include Developer
|
|
627
|
+
const MISSING_SEED_ROLES_MESSAGE = "Roles must include Developer.";
|
|
627
628
|
const DUPLICATE_ROLE_SLUG_MESSAGE = "Each role needs a unique slug.";
|
|
628
629
|
const DUPLICATE_ROLE_NAME_MESSAGE = "Each role needs a unique name.";
|
|
629
630
|
const INVALID_ROLE_NAME_MESSAGE = "Use letters and spaces only.";
|
|
@@ -693,7 +694,7 @@ function parseRolesMatrix(value) {
|
|
|
693
694
|
seen.add(parsed.role);
|
|
694
695
|
rows.push(parsed);
|
|
695
696
|
}
|
|
696
|
-
if (
|
|
697
|
+
if (!seen.has("developer")) return {
|
|
697
698
|
ok: false,
|
|
698
699
|
message: MISSING_SEED_ROLES_MESSAGE
|
|
699
700
|
};
|
|
@@ -1596,7 +1597,7 @@ function createRoles({ extras = [] } = {}) {
|
|
|
1596
1597
|
singular: "Role",
|
|
1597
1598
|
plural: "Roles"
|
|
1598
1599
|
},
|
|
1599
|
-
minRows:
|
|
1600
|
+
minRows: 1,
|
|
1600
1601
|
required: true,
|
|
1601
1602
|
defaultValue: defaultRolesFieldValue(extras),
|
|
1602
1603
|
validate: validateRolesMatrix,
|
|
@@ -1653,9 +1654,9 @@ function createRoles({ extras = [] } = {}) {
|
|
|
1653
1654
|
//#endregion
|
|
1654
1655
|
//#region src/roles/seed.ts
|
|
1655
1656
|
/**
|
|
1656
|
-
* Writes the default matrix (
|
|
1657
|
-
* migration `up()`. Never writes a user row —
|
|
1658
|
-
* person stays a site concern.
|
|
1657
|
+
* Writes the default matrix (Developer, Admin, Designer, Author plus any
|
|
1658
|
+
* site extras). For a site's migration `up()`. Never writes a user row —
|
|
1659
|
+
* seeding `developer` on a person stays a site concern.
|
|
1659
1660
|
*/
|
|
1660
1661
|
async function seedRoles(payload, extras = []) {
|
|
1661
1662
|
return payload.updateGlobal({
|
|
@@ -2036,7 +2037,6 @@ function createUsers({ secureCookies, rolesField, extras = [] }) {
|
|
|
2036
2037
|
type: "select",
|
|
2037
2038
|
hasMany: true,
|
|
2038
2039
|
required: true,
|
|
2039
|
-
defaultValue: ["author"],
|
|
2040
2040
|
saveToJWT: true,
|
|
2041
2041
|
options: roleSelectOptions(fallback),
|
|
2042
2042
|
admin: {
|
|
@@ -2097,6 +2097,444 @@ function createMedia({ staticDir = "media", mimeTypes = ["image/*"], imageSizes
|
|
|
2097
2097
|
};
|
|
2098
2098
|
}
|
|
2099
2099
|
//#endregion
|
|
2100
|
+
//#region src/admin-nav/fields.ts
|
|
2101
|
+
const ADMIN_NAV = "@bison-lab/payload-core/admin#AdminNav";
|
|
2102
|
+
const ADMIN_NAV_ROW_LABEL = "@bison-lab/payload-core/admin#AdminNavRowLabel";
|
|
2103
|
+
const ADMIN_NAV_ENTITY_FIELD = "@bison-lab/payload-core/admin#AdminNavEntityField";
|
|
2104
|
+
//#endregion
|
|
2105
|
+
//#region src/admin-nav/types.ts
|
|
2106
|
+
/**
|
|
2107
|
+
* Developer-owned admin sidebar. SPI-10 skins this with AppSidebarBlock;
|
|
2108
|
+
* this package ships the document and the default Nav. A consuming site
|
|
2109
|
+
* waits for SPI-97 after this and BIS-110 publish.
|
|
2110
|
+
*/
|
|
2111
|
+
const ADMIN_NAV_SLUG = "admin-nav";
|
|
2112
|
+
//#endregion
|
|
2113
|
+
//#region src/admin-nav/validate.ts
|
|
2114
|
+
const UNKNOWN_ENTITY_MESSAGE = "Not in this site's config.";
|
|
2115
|
+
/**
|
|
2116
|
+
* A Developer cannot invent a collection or global that is not registered.
|
|
2117
|
+
*/
|
|
2118
|
+
const validateAdminNavSlug = (value, { req, siblingData }) => {
|
|
2119
|
+
if (typeof value !== "string" || value === "") return true;
|
|
2120
|
+
const type = siblingData && typeof siblingData === "object" && "type" in siblingData ? siblingData.type : null;
|
|
2121
|
+
return ((type === "global" ? req.payload?.config?.globals : type === "collection" ? req.payload?.config?.collections : []) ?? []).map((entity) => entity.slug).includes(value) || UNKNOWN_ENTITY_MESSAGE;
|
|
2122
|
+
};
|
|
2123
|
+
//#endregion
|
|
2124
|
+
//#region src/admin-nav/global.ts
|
|
2125
|
+
const groupsField = {
|
|
2126
|
+
name: "groups",
|
|
2127
|
+
type: "array",
|
|
2128
|
+
label: "Groups",
|
|
2129
|
+
labels: {
|
|
2130
|
+
singular: "Group",
|
|
2131
|
+
plural: "Groups"
|
|
2132
|
+
},
|
|
2133
|
+
admin: {
|
|
2134
|
+
components: { RowLabel: ADMIN_NAV_ROW_LABEL },
|
|
2135
|
+
description: "Sidebar headers and the collections or globals under each. Drag to reorder. An empty header still shows.",
|
|
2136
|
+
initCollapsed: false
|
|
2137
|
+
},
|
|
2138
|
+
fields: [{
|
|
2139
|
+
name: "label",
|
|
2140
|
+
type: "text",
|
|
2141
|
+
label: "Header"
|
|
2142
|
+
}, {
|
|
2143
|
+
name: "items",
|
|
2144
|
+
type: "array",
|
|
2145
|
+
label: "Items",
|
|
2146
|
+
labels: {
|
|
2147
|
+
singular: "Item",
|
|
2148
|
+
plural: "Items"
|
|
2149
|
+
},
|
|
2150
|
+
fields: [{
|
|
2151
|
+
name: "type",
|
|
2152
|
+
type: "select",
|
|
2153
|
+
label: "Type",
|
|
2154
|
+
required: true,
|
|
2155
|
+
defaultValue: "collection",
|
|
2156
|
+
options: [{
|
|
2157
|
+
label: "Collection",
|
|
2158
|
+
value: "collection"
|
|
2159
|
+
}, {
|
|
2160
|
+
label: "Global",
|
|
2161
|
+
value: "global"
|
|
2162
|
+
}]
|
|
2163
|
+
}, {
|
|
2164
|
+
name: "slug",
|
|
2165
|
+
type: "text",
|
|
2166
|
+
label: "Slug",
|
|
2167
|
+
required: true,
|
|
2168
|
+
validate: validateAdminNavSlug,
|
|
2169
|
+
admin: { components: { Field: ADMIN_NAV_ENTITY_FIELD } }
|
|
2170
|
+
}]
|
|
2171
|
+
}]
|
|
2172
|
+
};
|
|
2173
|
+
/**
|
|
2174
|
+
* Settings → Admin nav. Developer chrome, not a Features row. Save writes
|
|
2175
|
+
* immediately. The package Nav reads this document; an empty row falls
|
|
2176
|
+
* back to Payload's first-seen walk.
|
|
2177
|
+
*/
|
|
2178
|
+
function createAdminNav() {
|
|
2179
|
+
return {
|
|
2180
|
+
slug: ADMIN_NAV_SLUG,
|
|
2181
|
+
label: "Admin nav",
|
|
2182
|
+
admin: {
|
|
2183
|
+
group: "Settings",
|
|
2184
|
+
hidden: hideUnlessDeveloper,
|
|
2185
|
+
description: "Sidebar group headers and order. A site that never opens this screen looks the way Payload ordered it."
|
|
2186
|
+
},
|
|
2187
|
+
access: {
|
|
2188
|
+
read: isAuthenticated,
|
|
2189
|
+
update: ({ req }) => isDeveloper(req.user)
|
|
2190
|
+
},
|
|
2191
|
+
fields: [groupsField]
|
|
2192
|
+
};
|
|
2193
|
+
}
|
|
2194
|
+
//#endregion
|
|
2195
|
+
//#region src/admin-nav/plugin.ts
|
|
2196
|
+
/**
|
|
2197
|
+
* Sets `admin.components.Nav` to the package Nav. A consuming site must
|
|
2198
|
+
* not write its own Nav — SPI-10 is the later skin, and it reads
|
|
2199
|
+
* `resolveAdminNav` rather than a second layout source.
|
|
2200
|
+
*/
|
|
2201
|
+
const adminNav = definePlugin({
|
|
2202
|
+
slug: "admin-nav",
|
|
2203
|
+
order: 1e3,
|
|
2204
|
+
plugin: ({ config }) => ({
|
|
2205
|
+
...config,
|
|
2206
|
+
admin: {
|
|
2207
|
+
...config.admin,
|
|
2208
|
+
components: {
|
|
2209
|
+
...config.admin?.components,
|
|
2210
|
+
Nav: ADMIN_NAV
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
})
|
|
2214
|
+
});
|
|
2215
|
+
//#endregion
|
|
2216
|
+
//#region src/admin-nav/resolve.ts
|
|
2217
|
+
function sidebarGroup(group) {
|
|
2218
|
+
if (group === false) return false;
|
|
2219
|
+
if (typeof group === "string") return group;
|
|
2220
|
+
return "";
|
|
2221
|
+
}
|
|
2222
|
+
function asLabel(value, fallback) {
|
|
2223
|
+
return typeof value === "string" && value ? value : fallback;
|
|
2224
|
+
}
|
|
2225
|
+
function entityLabel(entity, type) {
|
|
2226
|
+
if (type === "collection") return asLabel(entity.labels?.plural, asLabel(entity.labels?.singular, entity.slug));
|
|
2227
|
+
return asLabel(entity.label, entity.slug);
|
|
2228
|
+
}
|
|
2229
|
+
function keyOf(type, slug) {
|
|
2230
|
+
return `${type}:${slug}`;
|
|
2231
|
+
}
|
|
2232
|
+
function catalog$1(config) {
|
|
2233
|
+
const collections = (config.collections ?? []).map((entity) => ({
|
|
2234
|
+
type: "collection",
|
|
2235
|
+
slug: entity.slug,
|
|
2236
|
+
label: entityLabel(entity, "collection"),
|
|
2237
|
+
group: sidebarGroup(entity.admin?.group)
|
|
2238
|
+
}));
|
|
2239
|
+
const globals = (config.globals ?? []).map((entity) => ({
|
|
2240
|
+
type: "global",
|
|
2241
|
+
slug: entity.slug,
|
|
2242
|
+
label: entityLabel(entity, "global"),
|
|
2243
|
+
group: sidebarGroup(entity.admin?.group)
|
|
2244
|
+
}));
|
|
2245
|
+
return [...collections, ...globals];
|
|
2246
|
+
}
|
|
2247
|
+
function defaultGroups(entities) {
|
|
2248
|
+
const groups = [];
|
|
2249
|
+
for (const entity of entities) {
|
|
2250
|
+
if (entity.group === false) continue;
|
|
2251
|
+
let group = groups.find((entry) => entry.label === entity.group);
|
|
2252
|
+
if (!group) {
|
|
2253
|
+
group = {
|
|
2254
|
+
label: entity.group,
|
|
2255
|
+
items: []
|
|
2256
|
+
};
|
|
2257
|
+
groups.push(group);
|
|
2258
|
+
}
|
|
2259
|
+
group.items.push({
|
|
2260
|
+
type: entity.type,
|
|
2261
|
+
slug: entity.slug,
|
|
2262
|
+
label: entity.label
|
|
2263
|
+
});
|
|
2264
|
+
}
|
|
2265
|
+
return groups;
|
|
2266
|
+
}
|
|
2267
|
+
function itemFromSaved(item, byKey) {
|
|
2268
|
+
const type = item.type === "global" || item.type === "collection" ? item.type : null;
|
|
2269
|
+
const slug = typeof item.slug === "string" ? item.slug : "";
|
|
2270
|
+
if (!type || !slug) return null;
|
|
2271
|
+
const entity = byKey.get(keyOf(type, slug));
|
|
2272
|
+
if (!entity || entity.group === false) return null;
|
|
2273
|
+
return {
|
|
2274
|
+
type,
|
|
2275
|
+
slug,
|
|
2276
|
+
label: entity.label
|
|
2277
|
+
};
|
|
2278
|
+
}
|
|
2279
|
+
function fromDocument(doc, entities) {
|
|
2280
|
+
const byKey = new Map(entities.map((entity) => [keyOf(entity.type, entity.slug), entity]));
|
|
2281
|
+
const groups = (doc.groups ?? []).map((row) => ({
|
|
2282
|
+
label: typeof row.label === "string" ? row.label : "",
|
|
2283
|
+
items: (row.items ?? []).flatMap((item) => {
|
|
2284
|
+
const resolved = itemFromSaved(item ?? {}, byKey);
|
|
2285
|
+
return resolved ? [resolved] : [];
|
|
2286
|
+
})
|
|
2287
|
+
}));
|
|
2288
|
+
const seen = new Set(groups.flatMap((group) => group.items.map((item) => keyOf(item.type, item.slug))));
|
|
2289
|
+
for (const entity of entities) {
|
|
2290
|
+
if (entity.group === false) continue;
|
|
2291
|
+
const key = keyOf(entity.type, entity.slug);
|
|
2292
|
+
if (seen.has(key)) continue;
|
|
2293
|
+
let group = groups.find((entry) => entry.label === entity.group);
|
|
2294
|
+
if (!group) {
|
|
2295
|
+
group = {
|
|
2296
|
+
label: entity.group,
|
|
2297
|
+
items: []
|
|
2298
|
+
};
|
|
2299
|
+
groups.push(group);
|
|
2300
|
+
}
|
|
2301
|
+
group.items.push({
|
|
2302
|
+
type: entity.type,
|
|
2303
|
+
slug: entity.slug,
|
|
2304
|
+
label: entity.label
|
|
2305
|
+
});
|
|
2306
|
+
seen.add(key);
|
|
2307
|
+
}
|
|
2308
|
+
return groups;
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* Layout for the package Nav (and later SPI-10). Permissions are
|
|
2312
|
+
* `visibleEntities` — this function does not re-derive access.
|
|
2313
|
+
*/
|
|
2314
|
+
function resolveAdminNav({ config, doc, visibleEntities }) {
|
|
2315
|
+
const entities = catalog$1(config);
|
|
2316
|
+
const saved = Array.isArray(doc?.groups) ? doc.groups : [];
|
|
2317
|
+
let groups = saved.length === 0 ? defaultGroups(entities) : fromDocument({ groups: saved }, entities);
|
|
2318
|
+
if (visibleEntities) {
|
|
2319
|
+
const collections = new Set(visibleEntities.collections ?? []);
|
|
2320
|
+
const globals = new Set(visibleEntities.globals ?? []);
|
|
2321
|
+
groups = groups.map((group) => ({
|
|
2322
|
+
...group,
|
|
2323
|
+
items: group.items.filter((item) => item.type === "collection" ? collections.has(item.slug) : globals.has(item.slug))
|
|
2324
|
+
}));
|
|
2325
|
+
}
|
|
2326
|
+
return groups;
|
|
2327
|
+
}
|
|
2328
|
+
//#endregion
|
|
2329
|
+
//#region src/navigation/link.ts
|
|
2330
|
+
/**
|
|
2331
|
+
* Same import-map string as `@bison-lab/payload-blocks`. A site that
|
|
2332
|
+
* already generates the blocks admin map gets the picker; a missing
|
|
2333
|
+
* entry renders the row as nothing, so `payload generate:importmap` is
|
|
2334
|
+
* part of adopting this factory.
|
|
2335
|
+
*/
|
|
2336
|
+
const LINK_FIELD = "@bison-lab/payload-blocks/admin#LinkField";
|
|
2337
|
+
function linkTypeOf(link) {
|
|
2338
|
+
if (link?.type === "external") return "external";
|
|
2339
|
+
if (link?.type === "page") return "page";
|
|
2340
|
+
return link?.href ? "external" : "page";
|
|
2341
|
+
}
|
|
2342
|
+
const whenPage = (_data, siblingData) => linkTypeOf(siblingData) === "page";
|
|
2343
|
+
const whenExternal = (_data, siblingData) => linkTypeOf(siblingData) === "external";
|
|
2344
|
+
function linkDestinationFields({ required = false, pagesCollection = "pages" } = {}) {
|
|
2345
|
+
return [{
|
|
2346
|
+
type: "row",
|
|
2347
|
+
admin: { components: { Field: LINK_FIELD } },
|
|
2348
|
+
fields: [
|
|
2349
|
+
{
|
|
2350
|
+
name: "type",
|
|
2351
|
+
type: "radio",
|
|
2352
|
+
label: "Goes to",
|
|
2353
|
+
defaultValue: "page",
|
|
2354
|
+
options: [{
|
|
2355
|
+
label: "Page",
|
|
2356
|
+
value: "page"
|
|
2357
|
+
}, {
|
|
2358
|
+
label: "URL",
|
|
2359
|
+
value: "external"
|
|
2360
|
+
}],
|
|
2361
|
+
admin: { layout: "horizontal" }
|
|
2362
|
+
},
|
|
2363
|
+
{
|
|
2364
|
+
name: "page",
|
|
2365
|
+
type: "relationship",
|
|
2366
|
+
relationTo: pagesCollection,
|
|
2367
|
+
required,
|
|
2368
|
+
filterOptions: { _status: { equals: "published" } },
|
|
2369
|
+
admin: { condition: whenPage }
|
|
2370
|
+
},
|
|
2371
|
+
{
|
|
2372
|
+
name: "href",
|
|
2373
|
+
type: "text",
|
|
2374
|
+
label: "URL",
|
|
2375
|
+
required,
|
|
2376
|
+
admin: {
|
|
2377
|
+
condition: whenExternal,
|
|
2378
|
+
description: "A full URL (\"https://example.com\"), \"mailto:\" or \"tel:\", or a site path (\"/contact\")."
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
]
|
|
2382
|
+
}];
|
|
2383
|
+
}
|
|
2384
|
+
function linkFields({ required = false, pagesCollection } = {}) {
|
|
2385
|
+
return [
|
|
2386
|
+
...linkDestinationFields({
|
|
2387
|
+
required,
|
|
2388
|
+
pagesCollection
|
|
2389
|
+
}),
|
|
2390
|
+
{
|
|
2391
|
+
name: "label",
|
|
2392
|
+
type: "text",
|
|
2393
|
+
label: "Label",
|
|
2394
|
+
required
|
|
2395
|
+
},
|
|
2396
|
+
{
|
|
2397
|
+
name: "newTab",
|
|
2398
|
+
type: "checkbox",
|
|
2399
|
+
label: "Open in a new tab",
|
|
2400
|
+
defaultValue: false
|
|
2401
|
+
}
|
|
2402
|
+
];
|
|
2403
|
+
}
|
|
2404
|
+
function linkField({ name = "link", label, admin, required, pagesCollection } = {}) {
|
|
2405
|
+
return {
|
|
2406
|
+
name,
|
|
2407
|
+
type: "group",
|
|
2408
|
+
fields: linkFields({
|
|
2409
|
+
required,
|
|
2410
|
+
pagesCollection
|
|
2411
|
+
}),
|
|
2412
|
+
...label === void 0 ? {} : { label },
|
|
2413
|
+
...admin === void 0 ? {} : { admin }
|
|
2414
|
+
};
|
|
2415
|
+
}
|
|
2416
|
+
function footerLinkFields({ required = false, pagesCollection } = {}) {
|
|
2417
|
+
return linkFields({
|
|
2418
|
+
required,
|
|
2419
|
+
pagesCollection
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
//#endregion
|
|
2423
|
+
//#region src/navigation/global.ts
|
|
2424
|
+
const refusePublishWithoutTick = async ({ data, req }) => {
|
|
2425
|
+
if (data._status !== "published") return data;
|
|
2426
|
+
if (!req.user) return data;
|
|
2427
|
+
if (await Promise.resolve(canPublish({ req }))) return data;
|
|
2428
|
+
throw new Forbidden();
|
|
2429
|
+
};
|
|
2430
|
+
/**
|
|
2431
|
+
* Header (`navigation` / `nav`) and Footer (`navigation-footer` / `navf`).
|
|
2432
|
+
* One Features tick (`navigation`). Independent Save / Publish / drafts —
|
|
2433
|
+
* a draft header does not publish the footer.
|
|
2434
|
+
*/
|
|
2435
|
+
function createNavigation({ blocks, footerColumnRowLabel, footerLinkRowLabel, preview, livePreview, previewButton, pagesCollection }) {
|
|
2436
|
+
if (blocks.length === 0) throw new Error("createNavigation needs at least one header block");
|
|
2437
|
+
const hidden = hideUnlessFeature(NAVIGATION_FEATURE);
|
|
2438
|
+
const update = canUseFeature(NAVIGATION_FEATURE);
|
|
2439
|
+
const previewAdmin = {
|
|
2440
|
+
...preview ? { preview } : {},
|
|
2441
|
+
...livePreview ? { livePreview } : {},
|
|
2442
|
+
...previewButton ? { components: { elements: { PreviewButton: previewButton } } } : {}
|
|
2443
|
+
};
|
|
2444
|
+
return [{
|
|
2445
|
+
slug: NAVIGATION_SLUG,
|
|
2446
|
+
dbName: "nav",
|
|
2447
|
+
label: "Header",
|
|
2448
|
+
admin: {
|
|
2449
|
+
group: "Navigation",
|
|
2450
|
+
hidden,
|
|
2451
|
+
description: "The public header. A draft never reaches the live site until you publish.",
|
|
2452
|
+
...previewAdmin
|
|
2453
|
+
},
|
|
2454
|
+
access: {
|
|
2455
|
+
read: () => true,
|
|
2456
|
+
readVersions: isAuthenticated,
|
|
2457
|
+
update
|
|
2458
|
+
},
|
|
2459
|
+
versions: { drafts: { autosave: { interval: 375 } } },
|
|
2460
|
+
hooks: { beforeChange: [refusePublishWithoutTick] },
|
|
2461
|
+
fields: [{
|
|
2462
|
+
name: "header",
|
|
2463
|
+
type: "group",
|
|
2464
|
+
label: false,
|
|
2465
|
+
fields: [{
|
|
2466
|
+
name: "items",
|
|
2467
|
+
type: "blocks",
|
|
2468
|
+
labels: {
|
|
2469
|
+
singular: "Item",
|
|
2470
|
+
plural: "Items"
|
|
2471
|
+
},
|
|
2472
|
+
blocks,
|
|
2473
|
+
admin: { description: "Bar items, left to right. A mega menu leads with the choice a visitor has to make and keeps the other groups as named lists. A plain link is a bar item with nothing to open. Column widths in a panel must add up to 100%." }
|
|
2474
|
+
}, linkField({
|
|
2475
|
+
name: "cta",
|
|
2476
|
+
label: "Header button",
|
|
2477
|
+
required: true,
|
|
2478
|
+
pagesCollection,
|
|
2479
|
+
admin: { description: "The pill on the right of the bar." }
|
|
2480
|
+
})]
|
|
2481
|
+
}]
|
|
2482
|
+
}, {
|
|
2483
|
+
slug: NAVIGATION_FOOTER_SLUG,
|
|
2484
|
+
dbName: NAVIGATION_FOOTER_DB_NAME,
|
|
2485
|
+
label: "Footer",
|
|
2486
|
+
admin: {
|
|
2487
|
+
group: "Navigation",
|
|
2488
|
+
hidden,
|
|
2489
|
+
description: "The public footer shortcut columns. A draft never reaches the live site until you publish.",
|
|
2490
|
+
...previewAdmin
|
|
2491
|
+
},
|
|
2492
|
+
access: {
|
|
2493
|
+
read: () => true,
|
|
2494
|
+
readVersions: isAuthenticated,
|
|
2495
|
+
update
|
|
2496
|
+
},
|
|
2497
|
+
versions: { drafts: { autosave: { interval: 375 } } },
|
|
2498
|
+
hooks: { beforeChange: [refusePublishWithoutTick] },
|
|
2499
|
+
fields: [{
|
|
2500
|
+
name: "footer",
|
|
2501
|
+
type: "group",
|
|
2502
|
+
label: false,
|
|
2503
|
+
fields: [{
|
|
2504
|
+
name: "columns",
|
|
2505
|
+
type: "array",
|
|
2506
|
+
dbName: "c",
|
|
2507
|
+
labels: {
|
|
2508
|
+
singular: "Column",
|
|
2509
|
+
plural: "Columns"
|
|
2510
|
+
},
|
|
2511
|
+
admin: {
|
|
2512
|
+
description: "A shortcut strip, not a sitemap. One entry per heading plus the few pages worth a standing link. Everything omitted here is still reachable from the header. Adding a link back to \"complete\" a column is the wrong instinct — the omissions are the point.",
|
|
2513
|
+
components: footerColumnRowLabel ? { RowLabel: footerColumnRowLabel } : void 0
|
|
2514
|
+
},
|
|
2515
|
+
fields: [{
|
|
2516
|
+
name: "heading",
|
|
2517
|
+
type: "text",
|
|
2518
|
+
required: true,
|
|
2519
|
+
label: "Heading"
|
|
2520
|
+
}, {
|
|
2521
|
+
name: "links",
|
|
2522
|
+
type: "array",
|
|
2523
|
+
labels: {
|
|
2524
|
+
singular: "Link",
|
|
2525
|
+
plural: "Links"
|
|
2526
|
+
},
|
|
2527
|
+
admin: { components: footerLinkRowLabel ? { RowLabel: footerLinkRowLabel } : void 0 },
|
|
2528
|
+
fields: footerLinkFields({
|
|
2529
|
+
required: true,
|
|
2530
|
+
pagesCollection
|
|
2531
|
+
})
|
|
2532
|
+
}]
|
|
2533
|
+
}]
|
|
2534
|
+
}]
|
|
2535
|
+
}];
|
|
2536
|
+
}
|
|
2537
|
+
//#endregion
|
|
2100
2538
|
//#region src/plugins/admin-only-api-tab.ts
|
|
2101
2539
|
function gateApiTab(entity) {
|
|
2102
2540
|
const components = entity.admin?.components;
|
|
@@ -2178,6 +2616,6 @@ const documentTitleActions = definePlugin({
|
|
|
2178
2616
|
plugin: ({ config }) => withTitleActions(config)
|
|
2179
2617
|
});
|
|
2180
2618
|
//#endregion
|
|
2181
|
-
export { BRAND_ASSETS_MIME_TYPES, BRAND_ASSETS_SLUG, CAPABILITIES, CAPABILITY_FEATURES, DEFAULT_ROLE_GRANTS, DEFAULT_ROLE_MATRIX, DESCRIPTION_LENGTH, DEVELOPER_DESCRIPTION, DOCUMENT_CREATE_NEW, DOCUMENT_TITLE_ACTIONS, DUPLICATE_ROLE_NAME_MESSAGE, DUPLICATE_ROLE_SLUG_MESSAGE, FEATURES_MATRIX_FIELD, FEATURES_SLUG, FEATURE_GROUPS, FEATURE_GROUP_LABELS, INVALID_ROLE_NAME_MESSAGE, LAST_ADMIN_DELETE_MESSAGE, LAST_ADMIN_DEMOTE_MESSAGE, LAST_USERS_TICK_MESSAGE, LOOK_FIELD, MISSING_PACKAGE_FEATURES_MESSAGE, MISSING_SEED_ROLES_MESSAGE, PACKAGE_FEATURES, PACKAGE_FEATURE_SLUGS, PAGE_EDITOR_SYSTEM_KEYS, ROLES, ROLES_FIELD, ROLES_FIELD_DESCRIPTION, ROLES_GLOBAL_DESCRIPTION, ROLES_GRANTS_FIELD, ROLES_MATRIX_FIELD, ROLES_ROW_LABEL, ROLES_SLUG, ROLE_LABELS, ROLE_NAME_FIELD, ROLE_SLUG_FIELD, SHARE_IMAGE_SIZE, SYSTEM_COLOR_KEYS, THEME_APPEARANCE_FIELD, THEME_APPEARANCE_SLUG, THEME_COLORS_SLUG, THEME_COLOR_FIELD, THEME_COLOR_SCALE_FIELD, THEME_CONTRAST_REPORT, THEME_DOCUMENT_CONTROLS, THEME_FEATURE_SLUGS, THEME_FONT_FIELD, THEME_GREY_SCALE_FIELD, THEME_IDENTITY_FALLBACK, THEME_IDENTITY_SLUG, THEME_LIBRARY_FIELD, THEME_PAIRING_FIELD, THEME_PREVIEW_BREAKPOINTS, THEME_PUBLISH_FIELD, THEME_SAVE_BUTTON, THEME_SECTION_HEADING, THEME_SLUG, THEME_TYPOGRAPHY_SLUG, adminOnlyApiTab, allowedFeaturesForUser, applyRoleSlugsFromNames, authenticatedOrPublished, canManageBrand, canManageContent, canPublish, canUseFeature, colorTokenField, createBrandAssets, createFeatures, createMedia, createPages, createRoles, createTheme, createUsers, defaultFeaturesFieldValue, defaultRolesFieldValue, deleteLibraryColor, developerOnlyAccess, documentCreateNew, documentTitle, documentTitleActions, featureCatalogue, featureGroupLabel, findColorTokens, findColorUsages, firstImageIn, getFeaturesMatrix, getRolesMatrix, hasCapability, hasFeature, hasGrant, hasRole, hideUnlessDeveloper, hideUnlessFeature, isAdmin, isAdminOrSelf, isAuthenticated, isDeveloper, isDeveloperTab, isFeatureGroupId, isFeatureSlug, isLockedFeature, isPackageFeatureSlug, isPrivilegedRole, isRole, isRoleName, isRoleSlug, lookField, noIndexField, normalizeSlug, normalizeStoredRoles, pageEditorLooks, pageEditorTokens, parseFeaturesMatrix, parseRolesMatrix, persistThemeChild, publishThemeChild, resetRolesMatrix, resolveThemeIdentity, rewriteColorToken, rewriteColorTokens, rewriteColorUsages, roleDescription, roleLabel, roleSelectOptions, sanitizeRoleNameInput, sanitizeSvg, seedFeatures, seedRoleRows, seedRoles, seedTheme, seoPlugin, slugField, slugifyRoleName, stampFeatureCatalogue, storedRoles, themeColorKeys, themeLibraryFromDoc, titleTemplate, truncateAtWord, validateFeaturesMatrix, validateRolesMatrix };
|
|
2619
|
+
export { ADMIN_NAV, ADMIN_NAV_ENTITY_FIELD, ADMIN_NAV_ROW_LABEL, ADMIN_NAV_SLUG, BRAND_ASSETS_MIME_TYPES, BRAND_ASSETS_SLUG, CAPABILITIES, CAPABILITY_FEATURES, DEFAULT_ROLE_GRANTS, DEFAULT_ROLE_MATRIX, DESCRIPTION_LENGTH, DEVELOPER_DESCRIPTION, DOCUMENT_CREATE_NEW, DOCUMENT_TITLE_ACTIONS, DUPLICATE_ROLE_NAME_MESSAGE, DUPLICATE_ROLE_SLUG_MESSAGE, FEATURES_MATRIX_FIELD, FEATURES_SLUG, FEATURE_GROUPS, FEATURE_GROUP_LABELS, INVALID_ROLE_NAME_MESSAGE, LAST_ADMIN_DELETE_MESSAGE, LAST_ADMIN_DEMOTE_MESSAGE, LAST_USERS_TICK_MESSAGE, LOOK_FIELD, MISSING_PACKAGE_FEATURES_MESSAGE, MISSING_SEED_ROLES_MESSAGE, NAVIGATION_DB_NAME, NAVIGATION_FEATURE, NAVIGATION_FOOTER_DB_NAME, NAVIGATION_FOOTER_SLUG, NAVIGATION_SLUG, PACKAGE_FEATURES, PACKAGE_FEATURE_SLUGS, PAGE_EDITOR_SYSTEM_KEYS, ROLES, ROLES_FIELD, ROLES_FIELD_DESCRIPTION, ROLES_GLOBAL_DESCRIPTION, ROLES_GRANTS_FIELD, ROLES_MATRIX_FIELD, ROLES_ROW_LABEL, ROLES_SLUG, ROLE_LABELS, ROLE_NAME_FIELD, ROLE_SLUG_FIELD, SHARE_IMAGE_SIZE, SYSTEM_COLOR_KEYS, THEME_APPEARANCE_FIELD, THEME_APPEARANCE_SLUG, THEME_COLORS_SLUG, THEME_COLOR_FIELD, THEME_COLOR_SCALE_FIELD, THEME_CONTRAST_REPORT, THEME_DOCUMENT_CONTROLS, THEME_FEATURE_SLUGS, THEME_FONT_FIELD, THEME_GREY_SCALE_FIELD, THEME_IDENTITY_FALLBACK, THEME_IDENTITY_SLUG, THEME_LIBRARY_FIELD, THEME_PAIRING_FIELD, THEME_PREVIEW_BREAKPOINTS, THEME_PUBLISH_FIELD, THEME_SAVE_BUTTON, THEME_SECTION_HEADING, THEME_SLUG, THEME_TYPOGRAPHY_SLUG, adminNav, adminOnlyApiTab, allowedFeaturesForUser, applyRoleSlugsFromNames, authenticatedOrPublished, canManageBrand, canManageContent, canPublish, canUseFeature, colorTokenField, createAdminNav, createBrandAssets, createFeatures, createMedia, createNavigation, createPages, createRoles, createTheme, createUsers, defaultFeaturesFieldValue, defaultRolesFieldValue, deleteLibraryColor, developerOnlyAccess, documentCreateNew, documentTitle, documentTitleActions, featureCatalogue, featureGroupLabel, findColorTokens, findColorUsages, firstImageIn, getFeaturesMatrix, getNavigation, getRolesMatrix, hasCapability, hasFeature, hasGrant, hasRole, hideUnlessDeveloper, hideUnlessFeature, isAdmin, isAdminOrSelf, isAuthenticated, isDeveloper, isDeveloperTab, isFeatureGroupId, isFeatureSlug, isLockedFeature, isPackageFeatureSlug, isPrivilegedRole, isRole, isRoleName, isRoleSlug, lookField, noIndexField, normalizeSlug, normalizeStoredRoles, pageEditorLooks, pageEditorTokens, parseFeaturesMatrix, parseRolesMatrix, persistThemeChild, publishThemeChild, resetRolesMatrix, resolveAdminNav, resolveThemeIdentity, rewriteColorToken, rewriteColorTokens, rewriteColorUsages, roleDescription, roleLabel, roleSelectOptions, sanitizeRoleNameInput, sanitizeSvg, seedFeatures, seedRoleRows, seedRoles, seedTheme, seoPlugin, slugField, slugifyRoleName, stampFeatureCatalogue, storedRoles, themeColorKeys, themeLibraryFromDoc, titleTemplate, truncateAtWord, validateFeaturesMatrix, validateRolesMatrix };
|
|
2182
2620
|
|
|
2183
2621
|
//# sourceMappingURL=index.mjs.map
|