@bison-lab/payload-core 3.13.0 → 3.14.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 +23 -16
- package/dist/access-B3LglN2J.mjs +662 -0
- package/dist/access-B3LglN2J.mjs.map +1 -0
- package/dist/admin.d.mts +25 -5
- package/dist/admin.d.mts.map +1 -1
- package/dist/admin.mjs +443 -178
- package/dist/admin.mjs.map +1 -1
- package/dist/{identity-LAzSeorC.mjs → identity-Dwyq8519.mjs} +1 -1
- package/dist/{identity-LAzSeorC.mjs.map → identity-Dwyq8519.mjs.map} +1 -1
- package/dist/index.d.mts +73 -46
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +55 -557
- package/dist/index.mjs.map +1 -1
- package/dist/{looks-C6kTjvk3.d.mts → looks-Xs6v5vYU.d.mts} +1 -1
- package/dist/{looks-C6kTjvk3.d.mts.map → looks-Xs6v5vYU.d.mts.map} +1 -1
- package/dist/metadata.d.mts +1 -1
- package/dist/metadata.mjs +1 -1
- package/dist/{share-image-C4ILz4p2.mjs → share-image-BlFAJLnd.mjs} +1 -1
- package/dist/{share-image-C4ILz4p2.mjs.map → share-image-BlFAJLnd.mjs.map} +1 -1
- package/dist/theme.d.mts +1 -1
- package/dist/theme.mjs +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 +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import {
|
|
1
|
+
import { $ as defaultFeaturesFieldValue, A as ROLES_SLUG, B as CAPABILITIES, C as DUPLICATE_ROLE_NAME_MESSAGE, D as MISSING_SEED_ROLES_MESSAGE, E as LAST_USERS_TICK_MESSAGE, F as resetRolesMatrix, G as THEME_FEATURE_SLUGS, H as DEFAULT_ROLE_GRANTS, I as roleDescription, J as isRoleSlug, K as isRole, L as roleSelectOptions, M as defaultRolesFieldValue, N as normalizeStoredRoles, O as ROLES_FIELD_DESCRIPTION, P as parseRolesMatrix, Q as MISSING_PACKAGE_FEATURES_MESSAGE, R as seedRoleRows, S as DEVELOPER_DESCRIPTION, T as INVALID_ROLE_NAME_MESSAGE, U as ROLES, V as CAPABILITY_FEATURES, W as ROLE_LABELS, X as sanitizeRoleNameInput, Y as roleLabel, Z as slugifyRoleName, _ as isDeveloper, a as hideUnlessFeature, at as FEATURES_SLUG, b as storedRoles, c as canManageContent, ct as PACKAGE_FEATURES, d as hasCapability, dt as isFeatureSlug, et as featureCatalogue, f as hasGrant, ft as isLockedFeature, g as isAuthenticated, h as isAdminOrSelf, i as hasFeature, it as validateFeaturesMatrix, j as applyRoleSlugsFromNames, k as ROLES_GLOBAL_DESCRIPTION, l as canPublish, lt as PACKAGE_FEATURE_SLUGS, m as isAdmin, n as canUseFeature, nt as parseFeaturesMatrix, o as authenticatedOrPublished, ot as FEATURE_GROUPS, p as hasRole, pt as isPackageFeatureSlug, q as isRoleName, r as getFeaturesMatrix, rt as stampFeatureCatalogue, s as canManageBrand, st as FEATURE_GROUP_LABELS, tt as featureGroupLabel, u as getRolesMatrix, ut as isFeatureGroupId, v as isDeveloperTab, w as DUPLICATE_ROLE_SLUG_MESSAGE, x as DEFAULT_ROLE_MATRIX, y as isPrivilegedRole, z as validateRolesMatrix } from "./access-B3LglN2J.mjs";
|
|
2
|
+
import { n as documentTitle, r as titleTemplate, t as SHARE_IMAGE_SIZE } from "./share-image-BlFAJLnd.mjs";
|
|
3
|
+
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-Dwyq8519.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";
|
|
@@ -752,6 +753,7 @@ function createTheme(options) {
|
|
|
752
753
|
lockDocuments: false,
|
|
753
754
|
admin: {
|
|
754
755
|
group: "Theme",
|
|
756
|
+
hidden: hideUnlessFeature("theme"),
|
|
755
757
|
hideAPIURL: true,
|
|
756
758
|
custom: adminCustom,
|
|
757
759
|
components: preview ? { elements: { beforeDocumentControls: [THEME_DOCUMENT_CONTROLS] } } : void 0
|
|
@@ -919,288 +921,27 @@ const THEME_PREVIEW_BREAKPOINTS = [
|
|
|
919
921
|
}
|
|
920
922
|
];
|
|
921
923
|
//#endregion
|
|
922
|
-
//#region src/roles/types.ts
|
|
923
|
-
/**
|
|
924
|
-
* The Roles Global a site's generated types will describe. Optional and
|
|
925
|
-
* nullable, no index signature: a generated Global is assignable to this,
|
|
926
|
-
* never the reverse.
|
|
927
|
-
*/
|
|
928
|
-
const ROLES = [
|
|
929
|
-
"developer",
|
|
930
|
-
"admin",
|
|
931
|
-
"designer",
|
|
932
|
-
"author"
|
|
933
|
-
];
|
|
934
|
-
const ROLE_LABELS = {
|
|
935
|
-
developer: "Developer",
|
|
936
|
-
admin: "Admin",
|
|
937
|
-
designer: "Designer",
|
|
938
|
-
author: "Author"
|
|
939
|
-
};
|
|
940
|
-
const CAPABILITIES = [
|
|
941
|
-
"content",
|
|
942
|
-
"brand",
|
|
943
|
-
"publish",
|
|
944
|
-
"users"
|
|
945
|
-
];
|
|
946
|
-
function isRole(value) {
|
|
947
|
-
return typeof value === "string" && ROLES.includes(value);
|
|
948
|
-
}
|
|
949
|
-
/** Lowercase slug: `editor`, `site-editor`. Empty and punctuation are out. */
|
|
950
|
-
function isRoleSlug(value) {
|
|
951
|
-
return typeof value === "string" && /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(value);
|
|
952
|
-
}
|
|
953
|
-
function roleLabel(role, label) {
|
|
954
|
-
const trimmed = typeof label === "string" ? label.trim() : "";
|
|
955
|
-
if (trimmed) return trimmed;
|
|
956
|
-
return isRole(role) ? ROLE_LABELS[role] : role;
|
|
957
|
-
}
|
|
958
|
-
//#endregion
|
|
959
|
-
//#region src/roles/matrix.ts
|
|
960
|
-
const ROLES_SLUG = "roles";
|
|
961
|
-
const ROLES_GLOBAL_DESCRIPTION = "Who may do what. Drag to change rank.";
|
|
962
|
-
const ROLES_FIELD_DESCRIPTION = "Drag to change rank. Ticks are Content, Brand, Publish, and Users.";
|
|
963
|
-
/**
|
|
964
|
-
* Default rank and ticks. Brand is Designer only. The API tab is not a
|
|
965
|
-
* column — it is locked to Developer in `isDeveloper`.
|
|
966
|
-
*/
|
|
967
|
-
const DEFAULT_ROLE_MATRIX = [
|
|
968
|
-
{
|
|
969
|
-
role: "developer",
|
|
970
|
-
content: true,
|
|
971
|
-
brand: true,
|
|
972
|
-
publish: true,
|
|
973
|
-
users: true
|
|
974
|
-
},
|
|
975
|
-
{
|
|
976
|
-
role: "admin",
|
|
977
|
-
content: true,
|
|
978
|
-
brand: false,
|
|
979
|
-
publish: true,
|
|
980
|
-
users: true
|
|
981
|
-
},
|
|
982
|
-
{
|
|
983
|
-
role: "designer",
|
|
984
|
-
content: false,
|
|
985
|
-
brand: true,
|
|
986
|
-
publish: false,
|
|
987
|
-
users: false
|
|
988
|
-
},
|
|
989
|
-
{
|
|
990
|
-
role: "author",
|
|
991
|
-
content: true,
|
|
992
|
-
brand: false,
|
|
993
|
-
publish: false,
|
|
994
|
-
users: false
|
|
995
|
-
}
|
|
996
|
-
];
|
|
997
|
-
const DEVELOPER_DESCRIPTION = "Everything Admin can do, plus the document API tab.";
|
|
998
|
-
const LAST_USERS_TICK_MESSAGE = "Keep Users ticked on at least one of Admin or Developer.";
|
|
999
|
-
const MISSING_SEED_ROLES_MESSAGE = "Roles must include Developer, Admin, Designer, and Author.";
|
|
1000
|
-
const DUPLICATE_ROLE_SLUG_MESSAGE = "Each role needs a unique slug.";
|
|
1001
|
-
const CAPABILITY_LABELS = {
|
|
1002
|
-
content: "Content",
|
|
1003
|
-
brand: "Brand",
|
|
1004
|
-
publish: "Publish",
|
|
1005
|
-
users: "Users"
|
|
1006
|
-
};
|
|
1007
|
-
function seedRoleRows(extras = []) {
|
|
1008
|
-
return [...DEFAULT_ROLE_MATRIX.map((row) => ({
|
|
1009
|
-
...row,
|
|
1010
|
-
label: isRole(row.role) ? ROLE_LABELS[row.role] : row.role
|
|
1011
|
-
})), ...extras.map((extra) => ({ ...extra }))];
|
|
1012
|
-
}
|
|
1013
|
-
function defaultRolesFieldValue(extras = []) {
|
|
1014
|
-
return seedRoleRows(extras).map((row) => ({
|
|
1015
|
-
id: row.role,
|
|
1016
|
-
...row
|
|
1017
|
-
}));
|
|
1018
|
-
}
|
|
1019
|
-
function readRoleRow(item) {
|
|
1020
|
-
const role = "role" in item ? item.role : void 0;
|
|
1021
|
-
if (typeof role !== "string" || role.trim() === "") return { error: DUPLICATE_ROLE_SLUG_MESSAGE };
|
|
1022
|
-
if (!isRoleSlug(role)) return { error: DUPLICATE_ROLE_SLUG_MESSAGE };
|
|
1023
|
-
return {
|
|
1024
|
-
id: role,
|
|
1025
|
-
role,
|
|
1026
|
-
label: roleLabel(role, "label" in item && typeof item.label === "string" ? item.label : void 0),
|
|
1027
|
-
content: Boolean("content" in item && item.content),
|
|
1028
|
-
brand: Boolean("brand" in item && item.brand),
|
|
1029
|
-
publish: Boolean("publish" in item && item.publish),
|
|
1030
|
-
users: Boolean("users" in item && item.users)
|
|
1031
|
-
};
|
|
1032
|
-
}
|
|
1033
|
-
function parseRolesMatrix(value) {
|
|
1034
|
-
if (!Array.isArray(value)) return {
|
|
1035
|
-
ok: false,
|
|
1036
|
-
message: MISSING_SEED_ROLES_MESSAGE
|
|
1037
|
-
};
|
|
1038
|
-
const rows = [];
|
|
1039
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1040
|
-
for (const item of value) {
|
|
1041
|
-
if (!item || typeof item !== "object") continue;
|
|
1042
|
-
const parsed = readRoleRow(item);
|
|
1043
|
-
if ("error" in parsed) return {
|
|
1044
|
-
ok: false,
|
|
1045
|
-
message: parsed.error
|
|
1046
|
-
};
|
|
1047
|
-
if (seen.has(parsed.role)) return {
|
|
1048
|
-
ok: false,
|
|
1049
|
-
message: DUPLICATE_ROLE_SLUG_MESSAGE
|
|
1050
|
-
};
|
|
1051
|
-
seen.add(parsed.role);
|
|
1052
|
-
rows.push(parsed);
|
|
1053
|
-
}
|
|
1054
|
-
if (ROLES.some((role) => !seen.has(role))) return {
|
|
1055
|
-
ok: false,
|
|
1056
|
-
message: MISSING_SEED_ROLES_MESSAGE
|
|
1057
|
-
};
|
|
1058
|
-
return {
|
|
1059
|
-
ok: true,
|
|
1060
|
-
rows
|
|
1061
|
-
};
|
|
1062
|
-
}
|
|
1063
|
-
function hasPrivilegedUsersTick(rows) {
|
|
1064
|
-
return rows.some((row) => (row.role === "admin" || row.role === "developer") && row.users);
|
|
1065
|
-
}
|
|
1066
|
-
function validateRolesMatrix(value) {
|
|
1067
|
-
const parsed = parseRolesMatrix(value);
|
|
1068
|
-
if (!parsed.ok) return parsed.message;
|
|
1069
|
-
if (!hasPrivilegedUsersTick(parsed.rows)) return LAST_USERS_TICK_MESSAGE;
|
|
1070
|
-
return true;
|
|
1071
|
-
}
|
|
1072
|
-
/**
|
|
1073
|
-
* Developer is exclusive. Admin does not swallow Designer: both store.
|
|
1074
|
-
* Unknown slugs (dropped catalogue keys such as `approver`) fall away unless
|
|
1075
|
-
* they appear on the matrix.
|
|
1076
|
-
*/
|
|
1077
|
-
function normalizeStoredRoles(value, matrix = DEFAULT_ROLE_MATRIX) {
|
|
1078
|
-
if (!Array.isArray(value)) return [];
|
|
1079
|
-
const allowed = new Set(matrix.map((row) => row.role));
|
|
1080
|
-
const roles = [...new Set(value.filter((entry) => typeof entry === "string" && allowed.has(entry)))];
|
|
1081
|
-
if (roles.includes("developer")) return ["developer"];
|
|
1082
|
-
return roles;
|
|
1083
|
-
}
|
|
1084
|
-
function roleSelectOptions(matrix = DEFAULT_ROLE_MATRIX) {
|
|
1085
|
-
return matrix.map((row) => ({
|
|
1086
|
-
label: roleLabel(row.role, row.label),
|
|
1087
|
-
value: row.role
|
|
1088
|
-
}));
|
|
1089
|
-
}
|
|
1090
|
-
/** Capability copy only. Developer names the API tab; nothing about MCP or seed. */
|
|
1091
|
-
function roleDescription(role, matrix = DEFAULT_ROLE_MATRIX) {
|
|
1092
|
-
if (role === "developer") return DEVELOPER_DESCRIPTION;
|
|
1093
|
-
const row = matrix.find((entry) => entry.role === role);
|
|
1094
|
-
if (!row) return "No capabilities";
|
|
1095
|
-
return CAPABILITIES.filter((capability) => row[capability]).map((capability) => CAPABILITY_LABELS[capability]).join(", ") || "No capabilities";
|
|
1096
|
-
}
|
|
1097
|
-
/**
|
|
1098
|
-
* Seed ticks and package labels come back; extra rows stay as they are.
|
|
1099
|
-
*/
|
|
1100
|
-
function resetRolesMatrix(current) {
|
|
1101
|
-
const extras = [];
|
|
1102
|
-
if (Array.isArray(current)) for (const item of current) {
|
|
1103
|
-
if (!item || typeof item !== "object") continue;
|
|
1104
|
-
const parsed = readRoleRow(item);
|
|
1105
|
-
if ("error" in parsed || isRole(parsed.role)) continue;
|
|
1106
|
-
extras.push(parsed);
|
|
1107
|
-
}
|
|
1108
|
-
return [...defaultRolesFieldValue(), ...extras];
|
|
1109
|
-
}
|
|
1110
|
-
//#endregion
|
|
1111
|
-
//#region src/roles/access.ts
|
|
1112
|
-
function isAccessArgs$1(value) {
|
|
1113
|
-
return typeof value === "object" && value !== null && "req" in value;
|
|
1114
|
-
}
|
|
1115
|
-
function storedRoles(user) {
|
|
1116
|
-
return Array.isArray(user?.roles) ? user.roles : [];
|
|
1117
|
-
}
|
|
1118
|
-
function hasRole(user, role) {
|
|
1119
|
-
return storedRoles(user).includes(role);
|
|
1120
|
-
}
|
|
1121
|
-
/** Not a tick. True only when `developer` is stored on the row. */
|
|
1122
|
-
function isDeveloper(user) {
|
|
1123
|
-
return hasRole(user, "developer");
|
|
1124
|
-
}
|
|
1125
|
-
function hasCapability(user, capability, matrix = DEFAULT_ROLE_MATRIX) {
|
|
1126
|
-
return storedRoles(user).some((role) => {
|
|
1127
|
-
return matrix.find((entry) => entry.role === role)?.[capability] === true;
|
|
1128
|
-
});
|
|
1129
|
-
}
|
|
1130
|
-
/**
|
|
1131
|
-
* Reads the saved Roles Global, falling back to the seed when the row is
|
|
1132
|
-
* empty, missing, or unreadable. Always override-access so a Designer
|
|
1133
|
-
* evaluating Theme does not have to read Settings → Roles.
|
|
1134
|
-
*/
|
|
1135
|
-
async function getRolesMatrix(req = {}, extras = []) {
|
|
1136
|
-
const fallback = seedRoleRows(extras);
|
|
1137
|
-
const findGlobal = req.payload?.findGlobal;
|
|
1138
|
-
if (typeof findGlobal !== "function") return fallback;
|
|
1139
|
-
try {
|
|
1140
|
-
const doc = await findGlobal({
|
|
1141
|
-
slug: ROLES_SLUG,
|
|
1142
|
-
overrideAccess: true,
|
|
1143
|
-
req
|
|
1144
|
-
});
|
|
1145
|
-
const parsed = parseRolesMatrix(doc && typeof doc === "object" && "roles" in doc ? doc.roles : void 0);
|
|
1146
|
-
return parsed.ok ? parsed.rows : fallback;
|
|
1147
|
-
} catch {
|
|
1148
|
-
return fallback;
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
function capabilityPredicate(capability) {
|
|
1152
|
-
function predicate(userOrArgs, matrix) {
|
|
1153
|
-
if (isAccessArgs$1(userOrArgs)) {
|
|
1154
|
-
const user = userOrArgs.req.user;
|
|
1155
|
-
if (matrix) return hasCapability(user, capability, matrix);
|
|
1156
|
-
return getRolesMatrix(userOrArgs.req).then((rows) => hasCapability(user, capability, rows));
|
|
1157
|
-
}
|
|
1158
|
-
return hasCapability(userOrArgs, capability, matrix ?? DEFAULT_ROLE_MATRIX);
|
|
1159
|
-
}
|
|
1160
|
-
return predicate;
|
|
1161
|
-
}
|
|
1162
|
-
const canManageContent = capabilityPredicate("content");
|
|
1163
|
-
const canManageBrand = capabilityPredicate("brand");
|
|
1164
|
-
const canPublish = capabilityPredicate("publish");
|
|
1165
|
-
/** Users tick on any held role. */
|
|
1166
|
-
const isAdmin = capabilityPredicate("users");
|
|
1167
|
-
/** This role id currently has the Users tick. */
|
|
1168
|
-
function isPrivilegedRole(role, matrix = DEFAULT_ROLE_MATRIX) {
|
|
1169
|
-
return typeof role === "string" && matrix.some((row) => row.role === role && row.users);
|
|
1170
|
-
}
|
|
1171
|
-
function isAuthenticated(userOrArgs) {
|
|
1172
|
-
if (isAccessArgs$1(userOrArgs)) return Boolean(userOrArgs.req.user);
|
|
1173
|
-
return Boolean(userOrArgs);
|
|
1174
|
-
}
|
|
1175
|
-
const isAdminOrSelf = async ({ req }) => {
|
|
1176
|
-
if (!req.user) return false;
|
|
1177
|
-
if (await isAdmin({ req })) return true;
|
|
1178
|
-
return { id: { equals: req.user.id } };
|
|
1179
|
-
};
|
|
1180
|
-
const authenticatedOrPublished = ({ req: { user } }) => {
|
|
1181
|
-
if (isAuthenticated(user)) return true;
|
|
1182
|
-
return { _status: { equals: "published" } };
|
|
1183
|
-
};
|
|
1184
|
-
/** API tab condition: Developer only, not the Users tick. */
|
|
1185
|
-
function isDeveloperTab({ req }) {
|
|
1186
|
-
return isDeveloper(req.user);
|
|
1187
|
-
}
|
|
1188
|
-
//#endregion
|
|
1189
924
|
//#region src/roles/fields.ts
|
|
1190
925
|
const ROLES_MATRIX_FIELD = "@bison-lab/payload-core/admin#RolesMatrixField";
|
|
1191
926
|
const ROLES_ROW_LABEL = "@bison-lab/payload-core/admin#RolesRowLabel";
|
|
1192
927
|
const ROLE_SLUG_FIELD = "@bison-lab/payload-core/admin#RoleSlugField";
|
|
928
|
+
const ROLE_NAME_FIELD = "@bison-lab/payload-core/admin#RoleNameField";
|
|
1193
929
|
const ROLES_FIELD = "@bison-lab/payload-core/admin#RolesField";
|
|
930
|
+
const ROLES_GRANTS_FIELD = "@bison-lab/payload-core/admin#RolesGrantsField";
|
|
1194
931
|
//#endregion
|
|
1195
932
|
//#region src/roles/global.ts
|
|
1196
|
-
const roleSlugValidate = (value
|
|
1197
|
-
if (
|
|
1198
|
-
if (typeof value !== "string" || value === "") return DUPLICATE_ROLE_SLUG_MESSAGE;
|
|
933
|
+
const roleSlugValidate = (value) => {
|
|
934
|
+
if (typeof value !== "string" || value === "") return true;
|
|
1199
935
|
return isRoleSlug(value) || "Each role needs a unique slug.";
|
|
1200
936
|
};
|
|
937
|
+
const roleNameValidate = (value) => {
|
|
938
|
+
if (typeof value !== "string" || value.trim() === "") return true;
|
|
939
|
+
return isRoleName(value) || "Use letters and spaces only.";
|
|
940
|
+
};
|
|
1201
941
|
/**
|
|
1202
|
-
* Settings → Roles. Rank is the array order (Payload's drag handle).
|
|
1203
|
-
* are
|
|
942
|
+
* Settings → Roles. Rank is the array order (Payload's drag handle).
|
|
943
|
+
* Ticks are released catalogue rows. Developer is implicit and shown
|
|
944
|
+
* only to a Developer, with every catalogue tick locked on.
|
|
1204
945
|
*/
|
|
1205
946
|
function createRoles({ extras = [] } = {}) {
|
|
1206
947
|
const rolesField = {
|
|
@@ -1215,6 +956,7 @@ function createRoles({ extras = [] } = {}) {
|
|
|
1215
956
|
required: true,
|
|
1216
957
|
defaultValue: defaultRolesFieldValue(extras),
|
|
1217
958
|
validate: validateRolesMatrix,
|
|
959
|
+
hooks: { beforeChange: [({ value }) => applyRoleSlugsFromNames(value)] },
|
|
1218
960
|
admin: {
|
|
1219
961
|
components: {
|
|
1220
962
|
Field: ROLES_MATRIX_FIELD,
|
|
@@ -1228,36 +970,23 @@ function createRoles({ extras = [] } = {}) {
|
|
|
1228
970
|
name: "role",
|
|
1229
971
|
type: "text",
|
|
1230
972
|
label: "Slug",
|
|
1231
|
-
required: true,
|
|
1232
973
|
validate: roleSlugValidate,
|
|
1233
|
-
|
|
1234
|
-
admin: { components: { Field: ROLE_SLUG_FIELD } }
|
|
974
|
+
admin: { hidden: true }
|
|
1235
975
|
},
|
|
1236
976
|
{
|
|
1237
977
|
name: "label",
|
|
1238
978
|
type: "text",
|
|
1239
979
|
label: "Name",
|
|
1240
|
-
required: true
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
name: "content",
|
|
1244
|
-
type: "checkbox",
|
|
1245
|
-
label: "Content"
|
|
1246
|
-
},
|
|
1247
|
-
{
|
|
1248
|
-
name: "brand",
|
|
1249
|
-
type: "checkbox",
|
|
1250
|
-
label: "Brand"
|
|
1251
|
-
},
|
|
1252
|
-
{
|
|
1253
|
-
name: "publish",
|
|
1254
|
-
type: "checkbox",
|
|
1255
|
-
label: "Publish"
|
|
980
|
+
required: true,
|
|
981
|
+
validate: roleNameValidate,
|
|
982
|
+
admin: { components: { Field: ROLE_NAME_FIELD } }
|
|
1256
983
|
},
|
|
1257
984
|
{
|
|
1258
|
-
name: "
|
|
1259
|
-
type: "
|
|
1260
|
-
label: "
|
|
985
|
+
name: "grants",
|
|
986
|
+
type: "json",
|
|
987
|
+
label: "Grants",
|
|
988
|
+
defaultValue: [],
|
|
989
|
+
admin: { components: { Field: ROLES_GRANTS_FIELD } }
|
|
1261
990
|
}
|
|
1262
991
|
]
|
|
1263
992
|
};
|
|
@@ -1266,11 +995,11 @@ function createRoles({ extras = [] } = {}) {
|
|
|
1266
995
|
label: "Roles",
|
|
1267
996
|
admin: {
|
|
1268
997
|
group: "Settings",
|
|
1269
|
-
hidden: (
|
|
998
|
+
hidden: hideUnlessFeature("roles"),
|
|
1270
999
|
description: ROLES_GLOBAL_DESCRIPTION
|
|
1271
1000
|
},
|
|
1272
1001
|
access: {
|
|
1273
|
-
read: (args) =>
|
|
1002
|
+
read: (args) => canUseFeature("roles")(args),
|
|
1274
1003
|
update: (args) => isAdmin(args)
|
|
1275
1004
|
},
|
|
1276
1005
|
fields: [rolesField]
|
|
@@ -1293,169 +1022,11 @@ async function seedRoles(payload, extras = []) {
|
|
|
1293
1022
|
//#region src/features/fields.ts
|
|
1294
1023
|
const FEATURES_MATRIX_FIELD = "@bison-lab/payload-core/admin#FeaturesMatrixField";
|
|
1295
1024
|
//#endregion
|
|
1296
|
-
//#region src/features/types.ts
|
|
1297
|
-
const FEATURES_SLUG = "features";
|
|
1298
|
-
const PACKAGE_FEATURE_SLUGS = [
|
|
1299
|
-
"pages",
|
|
1300
|
-
"media",
|
|
1301
|
-
"theme",
|
|
1302
|
-
"brand-assets",
|
|
1303
|
-
"users",
|
|
1304
|
-
"roles",
|
|
1305
|
-
"features"
|
|
1306
|
-
];
|
|
1307
|
-
/**
|
|
1308
|
-
* Package catalogue. Locked rows cannot be turned off. Empty Global falls
|
|
1309
|
-
* back to the named capability (Content → Pages/Media, Brand → Theme /
|
|
1310
|
-
* Brand assets, Users → Users/Roles/Features).
|
|
1311
|
-
*/
|
|
1312
|
-
const PACKAGE_FEATURES = [
|
|
1313
|
-
{
|
|
1314
|
-
slug: "pages",
|
|
1315
|
-
label: "Pages",
|
|
1316
|
-
fallback: "content",
|
|
1317
|
-
locked: false
|
|
1318
|
-
},
|
|
1319
|
-
{
|
|
1320
|
-
slug: "media",
|
|
1321
|
-
label: "Media",
|
|
1322
|
-
fallback: "content",
|
|
1323
|
-
locked: false
|
|
1324
|
-
},
|
|
1325
|
-
{
|
|
1326
|
-
slug: "theme",
|
|
1327
|
-
label: "Theme",
|
|
1328
|
-
fallback: "brand",
|
|
1329
|
-
locked: false
|
|
1330
|
-
},
|
|
1331
|
-
{
|
|
1332
|
-
slug: "brand-assets",
|
|
1333
|
-
label: "Brand assets",
|
|
1334
|
-
fallback: "brand",
|
|
1335
|
-
locked: false
|
|
1336
|
-
},
|
|
1337
|
-
{
|
|
1338
|
-
slug: "users",
|
|
1339
|
-
label: "Users",
|
|
1340
|
-
fallback: "users",
|
|
1341
|
-
locked: true
|
|
1342
|
-
},
|
|
1343
|
-
{
|
|
1344
|
-
slug: "roles",
|
|
1345
|
-
label: "Roles",
|
|
1346
|
-
fallback: "users",
|
|
1347
|
-
locked: true
|
|
1348
|
-
},
|
|
1349
|
-
{
|
|
1350
|
-
slug: "features",
|
|
1351
|
-
label: "Features",
|
|
1352
|
-
fallback: "users",
|
|
1353
|
-
locked: true
|
|
1354
|
-
}
|
|
1355
|
-
];
|
|
1356
|
-
function isPackageFeatureSlug(value) {
|
|
1357
|
-
return typeof value === "string" && PACKAGE_FEATURE_SLUGS.includes(value);
|
|
1358
|
-
}
|
|
1359
|
-
function isFeatureSlug(value) {
|
|
1360
|
-
return typeof value === "string" && /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(value);
|
|
1361
|
-
}
|
|
1362
|
-
function isLockedFeature(slug, locked) {
|
|
1363
|
-
if (locked === true) return true;
|
|
1364
|
-
return PACKAGE_FEATURES.find((feature) => feature.slug === slug)?.locked === true;
|
|
1365
|
-
}
|
|
1366
|
-
//#endregion
|
|
1367
|
-
//#region src/features/matrix.ts
|
|
1368
|
-
const MISSING_PACKAGE_FEATURES_MESSAGE = "Features must include Pages, Media, Theme, Brand assets, Users, Roles, and Features.";
|
|
1369
|
-
const LOCKED_FEATURE_MESSAGE = "Users, Roles, and Features cannot be turned off. Developer stays allowed on every row.";
|
|
1370
|
-
function featureCatalogue(extras = []) {
|
|
1371
|
-
return [...PACKAGE_FEATURES.map((feature) => ({ ...feature })), ...extras.map((extra) => ({
|
|
1372
|
-
slug: extra.slug,
|
|
1373
|
-
label: extra.label,
|
|
1374
|
-
fallback: null,
|
|
1375
|
-
locked: false
|
|
1376
|
-
}))];
|
|
1377
|
-
}
|
|
1378
|
-
function rolesForFeature(feature, matrix) {
|
|
1379
|
-
const allowed = new Set(["developer"]);
|
|
1380
|
-
if (feature.locked) {
|
|
1381
|
-
for (const row of matrix) allowed.add(row.role);
|
|
1382
|
-
return [...allowed];
|
|
1383
|
-
}
|
|
1384
|
-
if (feature.fallback) {
|
|
1385
|
-
for (const row of matrix) if (row[feature.fallback]) allowed.add(row.role);
|
|
1386
|
-
}
|
|
1387
|
-
return [...allowed];
|
|
1388
|
-
}
|
|
1389
|
-
function defaultFeaturesFieldValue(extras = [], matrix = DEFAULT_ROLE_MATRIX) {
|
|
1390
|
-
return featureCatalogue(extras).map((feature) => ({
|
|
1391
|
-
id: feature.slug,
|
|
1392
|
-
slug: feature.slug,
|
|
1393
|
-
label: feature.label,
|
|
1394
|
-
locked: feature.locked,
|
|
1395
|
-
roles: rolesForFeature(feature, matrix)
|
|
1396
|
-
}));
|
|
1397
|
-
}
|
|
1398
|
-
function parseFeaturesMatrix(value) {
|
|
1399
|
-
if (!Array.isArray(value) || value.length === 0) return {
|
|
1400
|
-
ok: false,
|
|
1401
|
-
message: MISSING_PACKAGE_FEATURES_MESSAGE
|
|
1402
|
-
};
|
|
1403
|
-
const rows = [];
|
|
1404
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1405
|
-
for (const item of value) {
|
|
1406
|
-
if (!item || typeof item !== "object") continue;
|
|
1407
|
-
const slug = "slug" in item ? item.slug : void 0;
|
|
1408
|
-
if (!isFeatureSlug(slug) || seen.has(slug)) continue;
|
|
1409
|
-
seen.add(slug);
|
|
1410
|
-
const rawRoles = "roles" in item && Array.isArray(item.roles) ? item.roles : [];
|
|
1411
|
-
const roles = [];
|
|
1412
|
-
for (const role of rawRoles) if (typeof role === "string" && !roles.includes(role)) roles.push(role);
|
|
1413
|
-
const label = "label" in item && typeof item.label === "string" ? item.label : slug;
|
|
1414
|
-
rows.push({
|
|
1415
|
-
id: slug,
|
|
1416
|
-
slug,
|
|
1417
|
-
label,
|
|
1418
|
-
locked: isLockedFeature(slug, "locked" in item ? Boolean(item.locked) : void 0),
|
|
1419
|
-
roles
|
|
1420
|
-
});
|
|
1421
|
-
}
|
|
1422
|
-
if (PACKAGE_FEATURES.some((feature) => !seen.has(feature.slug))) return {
|
|
1423
|
-
ok: false,
|
|
1424
|
-
message: MISSING_PACKAGE_FEATURES_MESSAGE
|
|
1425
|
-
};
|
|
1426
|
-
return {
|
|
1427
|
-
ok: true,
|
|
1428
|
-
rows
|
|
1429
|
-
};
|
|
1430
|
-
}
|
|
1431
|
-
function enforceFeatureLocks(rows, matrix = DEFAULT_ROLE_MATRIX) {
|
|
1432
|
-
const roleSlugs = matrix.map((row) => row.role);
|
|
1433
|
-
return rows.map((row) => {
|
|
1434
|
-
const roles = new Set(row.roles ?? []);
|
|
1435
|
-
roles.add("developer");
|
|
1436
|
-
if (isLockedFeature(row.slug, row.locked)) for (const role of roleSlugs) roles.add(role);
|
|
1437
|
-
return {
|
|
1438
|
-
...row,
|
|
1439
|
-
roles: [...roles]
|
|
1440
|
-
};
|
|
1441
|
-
});
|
|
1442
|
-
}
|
|
1443
|
-
function validateFeaturesMatrix(value, extras = [], matrix = DEFAULT_ROLE_MATRIX) {
|
|
1444
|
-
const parsed = parseFeaturesMatrix(value);
|
|
1445
|
-
if (!parsed.ok) return parsed.message;
|
|
1446
|
-
const allowed = new Set(featureCatalogue(extras).map((feature) => feature.slug));
|
|
1447
|
-
if (parsed.rows.some((row) => !allowed.has(row.slug))) return MISSING_PACKAGE_FEATURES_MESSAGE;
|
|
1448
|
-
for (const row of parsed.rows) {
|
|
1449
|
-
if (!row.roles?.includes("developer")) return LOCKED_FEATURE_MESSAGE;
|
|
1450
|
-
if (isLockedFeature(row.slug, row.locked) && matrix.some((role) => !row.roles?.includes(role.role))) return LOCKED_FEATURE_MESSAGE;
|
|
1451
|
-
}
|
|
1452
|
-
return true;
|
|
1453
|
-
}
|
|
1454
|
-
//#endregion
|
|
1455
1025
|
//#region src/features/global.ts
|
|
1456
1026
|
/**
|
|
1457
|
-
* Settings → Features.
|
|
1458
|
-
*
|
|
1027
|
+
* Settings → Features. One release switch per catalogue row. Off hides
|
|
1028
|
+
* the tick on Roles; Developer still has the feature. This screen is
|
|
1029
|
+
* not itself a row.
|
|
1459
1030
|
*/
|
|
1460
1031
|
function createFeatures({ extras = [] } = {}) {
|
|
1461
1032
|
const catalogue = featureCatalogue(extras);
|
|
@@ -1464,12 +1035,12 @@ function createFeatures({ extras = [] } = {}) {
|
|
|
1464
1035
|
label: "Features",
|
|
1465
1036
|
admin: {
|
|
1466
1037
|
group: "Settings",
|
|
1467
|
-
hidden: ({ user }) => !
|
|
1468
|
-
description: "
|
|
1038
|
+
hidden: ({ user }) => !isDeveloper(user),
|
|
1039
|
+
description: "Which features other people may be granted on Roles."
|
|
1469
1040
|
},
|
|
1470
1041
|
access: {
|
|
1471
|
-
read: (
|
|
1472
|
-
update: (
|
|
1042
|
+
read: ({ req }) => isDeveloper(req.user),
|
|
1043
|
+
update: ({ req }) => isDeveloper(req.user)
|
|
1473
1044
|
},
|
|
1474
1045
|
fields: [{
|
|
1475
1046
|
name: "features",
|
|
@@ -1483,16 +1054,14 @@ function createFeatures({ extras = [] } = {}) {
|
|
|
1483
1054
|
maxRows: catalogue.length,
|
|
1484
1055
|
required: true,
|
|
1485
1056
|
defaultValue: defaultFeaturesFieldValue(extras),
|
|
1486
|
-
validate:
|
|
1487
|
-
|
|
1488
|
-
},
|
|
1489
|
-
hooks: { beforeChange: [async ({ value, req }) => {
|
|
1057
|
+
validate: (value) => validateFeaturesMatrix(value, extras),
|
|
1058
|
+
hooks: { beforeChange: [({ value }) => {
|
|
1490
1059
|
if (!Array.isArray(value)) return value;
|
|
1491
|
-
return
|
|
1060
|
+
return stampFeatureCatalogue(value, extras);
|
|
1492
1061
|
}] },
|
|
1493
1062
|
admin: {
|
|
1494
1063
|
components: { Field: FEATURES_MATRIX_FIELD },
|
|
1495
|
-
description: "
|
|
1064
|
+
description: "Release a feature so it can be assigned on Roles. Off keeps it Developer-only.",
|
|
1496
1065
|
initCollapsed: false
|
|
1497
1066
|
},
|
|
1498
1067
|
fields: [
|
|
@@ -1511,16 +1080,16 @@ function createFeatures({ extras = [] } = {}) {
|
|
|
1511
1080
|
admin: { readOnly: true }
|
|
1512
1081
|
},
|
|
1513
1082
|
{
|
|
1514
|
-
name: "
|
|
1515
|
-
type: "
|
|
1516
|
-
label: "
|
|
1083
|
+
name: "group",
|
|
1084
|
+
type: "text",
|
|
1085
|
+
label: "Group",
|
|
1517
1086
|
admin: { hidden: true }
|
|
1518
1087
|
},
|
|
1519
1088
|
{
|
|
1520
|
-
name: "
|
|
1521
|
-
type: "
|
|
1522
|
-
label: "
|
|
1523
|
-
|
|
1089
|
+
name: "released",
|
|
1090
|
+
type: "checkbox",
|
|
1091
|
+
label: "Released",
|
|
1092
|
+
admin: { hidden: true }
|
|
1524
1093
|
}
|
|
1525
1094
|
]
|
|
1526
1095
|
}]
|
|
@@ -1539,80 +1108,6 @@ async function seedFeatures(payload, extras = []) {
|
|
|
1539
1108
|
});
|
|
1540
1109
|
}
|
|
1541
1110
|
//#endregion
|
|
1542
|
-
//#region src/features/access.ts
|
|
1543
|
-
function isAccessArgs(value) {
|
|
1544
|
-
return typeof value === "object" && value !== null && "req" in value;
|
|
1545
|
-
}
|
|
1546
|
-
function fallbackFeature(user, slug, matrix) {
|
|
1547
|
-
const pack = PACKAGE_FEATURES.find((feature) => feature.slug === slug);
|
|
1548
|
-
if (!pack) return false;
|
|
1549
|
-
return hasCapability(user, pack.fallback, matrix);
|
|
1550
|
-
}
|
|
1551
|
-
/**
|
|
1552
|
-
* True when any stored role is on the feature row. An empty grid falls
|
|
1553
|
-
* back to the capability map. Developer is always allowed.
|
|
1554
|
-
*/
|
|
1555
|
-
function hasFeature(user, slug, features = null, matrix = DEFAULT_ROLE_MATRIX) {
|
|
1556
|
-
if (isDeveloper(user)) return true;
|
|
1557
|
-
if (!user) return false;
|
|
1558
|
-
if (!features || features.length === 0) return fallbackFeature(user, slug, matrix);
|
|
1559
|
-
const row = features.find((entry) => entry.slug === slug);
|
|
1560
|
-
if (!row) return false;
|
|
1561
|
-
const allowed = row.roles ?? [];
|
|
1562
|
-
return storedRoles(user).some((role) => allowed.includes(role));
|
|
1563
|
-
}
|
|
1564
|
-
/**
|
|
1565
|
-
* Reads the saved Features Global. `null` means empty or unreadable — callers
|
|
1566
|
-
* fall back to the capability map. Always override-access.
|
|
1567
|
-
*/
|
|
1568
|
-
async function getFeaturesMatrix(req = {}) {
|
|
1569
|
-
const findGlobal = req.payload?.findGlobal;
|
|
1570
|
-
if (typeof findGlobal !== "function") return null;
|
|
1571
|
-
try {
|
|
1572
|
-
const doc = await findGlobal({
|
|
1573
|
-
slug: FEATURES_SLUG,
|
|
1574
|
-
overrideAccess: true,
|
|
1575
|
-
req
|
|
1576
|
-
});
|
|
1577
|
-
const parsed = parseFeaturesMatrix(doc && typeof doc === "object" && "features" in doc ? doc.features : void 0);
|
|
1578
|
-
if (!parsed.ok) return null;
|
|
1579
|
-
const matrix = await getRolesMatrix(req);
|
|
1580
|
-
return enforceFeatureLocks(parsed.rows, matrix);
|
|
1581
|
-
} catch {
|
|
1582
|
-
return null;
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
/**
|
|
1586
|
-
* Access / nav helper for one catalogue slug. Sync against a passed grid;
|
|
1587
|
-
* async when given `req` so it can read both Globals.
|
|
1588
|
-
*/
|
|
1589
|
-
function canUseFeature(slug) {
|
|
1590
|
-
function predicate(userOrArgs, features, roles) {
|
|
1591
|
-
if (isAccessArgs(userOrArgs)) {
|
|
1592
|
-
const user = userOrArgs.req.user;
|
|
1593
|
-
if (features !== void 0) return hasFeature(user, slug, features, roles ?? DEFAULT_ROLE_MATRIX);
|
|
1594
|
-
return Promise.all([getFeaturesMatrix(userOrArgs.req), getRolesMatrix(userOrArgs.req)]).then(([grid, matrix]) => hasFeature(user, slug, grid, matrix));
|
|
1595
|
-
}
|
|
1596
|
-
return hasFeature(userOrArgs, slug, features ?? null, roles ?? DEFAULT_ROLE_MATRIX);
|
|
1597
|
-
}
|
|
1598
|
-
return predicate;
|
|
1599
|
-
}
|
|
1600
|
-
/** `admin.hidden`: hide when the login cannot use the feature. */
|
|
1601
|
-
function hideUnlessFeature(slug) {
|
|
1602
|
-
return (args) => {
|
|
1603
|
-
const user = args.user;
|
|
1604
|
-
if (args.req) {
|
|
1605
|
-
const result = canUseFeature(slug)({ req: {
|
|
1606
|
-
...args.req,
|
|
1607
|
-
user
|
|
1608
|
-
} });
|
|
1609
|
-
if (result instanceof Promise) return result.then((ok) => !ok);
|
|
1610
|
-
return !result;
|
|
1611
|
-
}
|
|
1612
|
-
return !canUseFeature(slug)(user ?? null);
|
|
1613
|
-
};
|
|
1614
|
-
}
|
|
1615
|
-
//#endregion
|
|
1616
1111
|
//#region src/fields/slug.ts
|
|
1617
1112
|
/**
|
|
1618
1113
|
* A stored slug from whatever was typed: lowercased, with any run of
|
|
@@ -1712,15 +1207,15 @@ function createPages({ heroBlocks, isReservedSlug, layoutBlocks, previewPath, pr
|
|
|
1712
1207
|
"_status",
|
|
1713
1208
|
"updatedAt"
|
|
1714
1209
|
],
|
|
1715
|
-
hidden: hideUnlessFeature("
|
|
1210
|
+
hidden: hideUnlessFeature("content"),
|
|
1716
1211
|
preview: (doc) => previewPath(typeof doc.slug === "string" ? doc.slug : ""),
|
|
1717
1212
|
...previewButton ? { components: { edit: { PreviewButton: previewButton } } } : {}
|
|
1718
1213
|
},
|
|
1719
1214
|
access: {
|
|
1720
1215
|
read: authenticatedOrPublished,
|
|
1721
1216
|
readVersions: isAuthenticated,
|
|
1722
|
-
create: canUseFeature("
|
|
1723
|
-
update: canUseFeature("
|
|
1217
|
+
create: canUseFeature("content"),
|
|
1218
|
+
update: canUseFeature("content"),
|
|
1724
1219
|
delete: isAdmin
|
|
1725
1220
|
},
|
|
1726
1221
|
versions: {
|
|
@@ -1791,7 +1286,7 @@ async function lockLastAdminDecision(req) {
|
|
|
1791
1286
|
});
|
|
1792
1287
|
}
|
|
1793
1288
|
function privilegedRoles(matrix) {
|
|
1794
|
-
return matrix.filter((row) => row.
|
|
1289
|
+
return matrix.filter((row) => isPrivilegedRole(row.role, matrix)).map((row) => row.role);
|
|
1795
1290
|
}
|
|
1796
1291
|
function holdsPrivilegedRole(roles, matrix) {
|
|
1797
1292
|
return Array.isArray(roles) && roles.some((role) => isPrivilegedRole(role, matrix));
|
|
@@ -1847,13 +1342,16 @@ function createUsers({ secureCookies, rolesField, extras = [] }) {
|
|
|
1847
1342
|
"lastName",
|
|
1848
1343
|
"roles"
|
|
1849
1344
|
],
|
|
1850
|
-
hidden: (
|
|
1345
|
+
hidden: hideUnlessFeature("users")
|
|
1851
1346
|
},
|
|
1852
1347
|
access: {
|
|
1853
1348
|
create: isAdmin,
|
|
1854
1349
|
delete: isAdmin,
|
|
1855
1350
|
unlock: isAdmin,
|
|
1856
|
-
read:
|
|
1351
|
+
read: async (args) => {
|
|
1352
|
+
if (await Promise.resolve(canUseFeature("users")(args))) return true;
|
|
1353
|
+
return isAdminOrSelf(args);
|
|
1354
|
+
},
|
|
1857
1355
|
update: isAdminOrSelf
|
|
1858
1356
|
},
|
|
1859
1357
|
hooks: {
|
|
@@ -1972,6 +1470,6 @@ const adminOnlyApiTab = definePlugin({
|
|
|
1972
1470
|
})
|
|
1973
1471
|
});
|
|
1974
1472
|
//#endregion
|
|
1975
|
-
export { BRAND_ASSETS_MIME_TYPES, BRAND_ASSETS_SLUG, CAPABILITIES, DEFAULT_ROLE_MATRIX, DESCRIPTION_LENGTH, DEVELOPER_DESCRIPTION, DUPLICATE_ROLE_SLUG_MESSAGE, FEATURES_MATRIX_FIELD, FEATURES_SLUG, LAST_ADMIN_DELETE_MESSAGE, LAST_ADMIN_DEMOTE_MESSAGE, LAST_USERS_TICK_MESSAGE,
|
|
1473
|
+
export { BRAND_ASSETS_MIME_TYPES, BRAND_ASSETS_SLUG, CAPABILITIES, CAPABILITY_FEATURES, DEFAULT_ROLE_GRANTS, DEFAULT_ROLE_MATRIX, DESCRIPTION_LENGTH, DEVELOPER_DESCRIPTION, 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, applyRoleSlugsFromNames, authenticatedOrPublished, canManageBrand, canManageContent, canPublish, canUseFeature, colorTokenField, createBrandAssets, createFeatures, createMedia, createPages, createRoles, createTheme, createUsers, defaultFeaturesFieldValue, defaultRolesFieldValue, deleteLibraryColor, documentTitle, featureCatalogue, featureGroupLabel, findColorTokens, findColorUsages, firstImageIn, getFeaturesMatrix, getRolesMatrix, hasCapability, hasFeature, hasGrant, hasRole, 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 };
|
|
1976
1474
|
|
|
1977
1475
|
//# sourceMappingURL=index.mjs.map
|