feat(foundry): support restricted subject aspects
This commit is contained in:
@@ -348,6 +348,9 @@ function validateMapDataProductBinding(value) {
|
||||
const joinToBindingId = value.joinToBindingId === undefined
|
||||
? null
|
||||
: requireNonEmptyString(value.joinToBindingId, "invalid_map_data_product_join_binding_id", 128);
|
||||
const dataClass = value.dataClass === undefined
|
||||
? "operational"
|
||||
: requireNonEmptyString(value.dataClass, "invalid_map_data_product_data_class", 32);
|
||||
if (!/^[A-Za-z0-9._:-]+$/.test(id)) throw applicationError("invalid_map_data_product_binding_id");
|
||||
if (!/^[A-Za-z0-9._:-]+$/.test(dataProductId)) throw applicationError("invalid_map_data_product_id");
|
||||
if (!/^[A-Za-z0-9-]+$/.test(slotId)) throw applicationError("invalid_map_data_product_slot");
|
||||
@@ -367,6 +370,9 @@ function validateMapDataProductBinding(value) {
|
||||
if (joinToBindingId && !/^[A-Za-z0-9._:-]+$/.test(joinToBindingId)) {
|
||||
throw applicationError("invalid_map_data_product_join_binding_id");
|
||||
}
|
||||
if (!new Set(["operational", "restricted"]).has(dataClass)) {
|
||||
throw applicationError("invalid_map_data_product_data_class");
|
||||
}
|
||||
if (Object.keys(value).some((key) => /(provider|tenant|connection|endpoint|url|credential|token|secret|payload)/i.test(key))) {
|
||||
throw applicationError("map_data_product_binding_contains_transport");
|
||||
}
|
||||
@@ -383,6 +389,7 @@ function validateMapDataProductBinding(value) {
|
||||
...(subjectDetailProfileId ? { subjectDetailProfileId } : {}),
|
||||
aspectId,
|
||||
...(joinToBindingId ? { joinToBindingId } : {}),
|
||||
dataClass,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -524,9 +531,27 @@ function validateMapPageLayout(value) {
|
||||
}
|
||||
}
|
||||
for (const primary of dataProductBindings.filter((binding) => !binding.joinToBindingId)) {
|
||||
const aspectIds = [primary, ...dataProductBindings.filter((binding) => binding.joinToBindingId === primary.id)]
|
||||
.map((binding) => binding.aspectId);
|
||||
const composition = [
|
||||
primary,
|
||||
...dataProductBindings.filter((binding) => binding.joinToBindingId === primary.id),
|
||||
];
|
||||
const aspectIds = composition.map((binding) => binding.aspectId);
|
||||
if (new Set(aspectIds).size !== aspectIds.length) throw applicationError("duplicate_map_data_product_aspect_id");
|
||||
const detailProfile = primary.subjectDetailProfileId
|
||||
? subjectDetailProfilesById.get(primary.subjectDetailProfileId)
|
||||
: null;
|
||||
if (!detailProfile) continue;
|
||||
const aspectsById = new Map(composition.map((binding) => [binding.aspectId, binding]));
|
||||
const detailFields = detailProfile.tabs.flatMap(
|
||||
(tab) => tab.sections.flatMap((section) => section.fields),
|
||||
);
|
||||
for (const field of detailFields) {
|
||||
const aspect = aspectsById.get(field.aspectId);
|
||||
if (!aspect) throw applicationError("map_subject_detail_profile_aspect_not_found");
|
||||
if (field.dataClass !== aspect.dataClass) {
|
||||
throw applicationError("map_subject_detail_profile_data_class_mismatch");
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
schemaVersion: 1,
|
||||
|
||||
Reference in New Issue
Block a user