@objectstack/lint 15.0.0 → 15.1.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/dist/index.cjs +26 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1119,6 +1119,7 @@ function validateRecordTitle(stack) {
|
|
|
1119
1119
|
// src/validate-semantic-roles.ts
|
|
1120
1120
|
var FIELD_GROUP_UNDECLARED = "field-group-undeclared";
|
|
1121
1121
|
var FIELD_GROUP_EMPTY = "field-group-empty";
|
|
1122
|
+
var FIELD_GROUP_SHADOWED = "field-group-shadowed";
|
|
1122
1123
|
var SEMANTIC_ROLE_FIELD_UNKNOWN = "semantic-role-field-unknown";
|
|
1123
1124
|
function asArray10(v) {
|
|
1124
1125
|
if (Array.isArray(v)) return v;
|
|
@@ -1192,6 +1193,31 @@ function validateSemanticRoles(stack) {
|
|
|
1192
1193
|
hint: `Fix the field name (highlightFields drives default columns, cards, previews and the detail highlight strip, in order).`
|
|
1193
1194
|
});
|
|
1194
1195
|
}
|
|
1196
|
+
const declaredStrings = highlights.filter(
|
|
1197
|
+
(h) => typeof h === "string" && h.length > 0
|
|
1198
|
+
);
|
|
1199
|
+
if (declaredStrings.length > 0 && declaredGroups.size > 0) {
|
|
1200
|
+
const declaredTitle = [obj.nameField, obj.primaryField, obj.displayNameField].find((v) => typeof v === "string" && v.length > 0 && fieldNames.has(v));
|
|
1201
|
+
const titleField = declaredTitle ?? ["name", "full_name", "title", "subject", "display_name"].find((c) => fieldNames.has(c));
|
|
1202
|
+
const stripSet = new Set(
|
|
1203
|
+
declaredStrings.filter((h) => h !== titleField).slice(0, 4)
|
|
1204
|
+
);
|
|
1205
|
+
const hiddenFromBody = new Set(stripSet);
|
|
1206
|
+
if (titleField) hiddenFromBody.add(titleField);
|
|
1207
|
+
for (const key of declaredGroups) {
|
|
1208
|
+
const members = Object.entries(fields).filter(([, f]) => f?.group === key && f?.hidden !== true).map(([fname]) => fname);
|
|
1209
|
+
if (members.length === 0) continue;
|
|
1210
|
+
if (!members.every((m) => hiddenFromBody.has(m))) continue;
|
|
1211
|
+
findings.push({
|
|
1212
|
+
severity: "warning",
|
|
1213
|
+
rule: FIELD_GROUP_SHADOWED,
|
|
1214
|
+
where,
|
|
1215
|
+
path: `${path}.fieldGroups`,
|
|
1216
|
+
message: `${objName}: every field in group "${key}" (${members.join(", ")}) is hoisted into the detail highlight strip (or is the record title) \u2014 the group renders on forms but never on detail pages`,
|
|
1217
|
+
hint: `Keep at least one non-highlighted field in "${key}", or remove the group if the strip already covers it. (Detail pages show the first 4 highlightFields as the top strip and hide them from the body.)`
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1195
1221
|
}
|
|
1196
1222
|
return findings;
|
|
1197
1223
|
}
|