in source/packages/services/assetlibrary/src/types/schemaValidator.full.service.ts [261:400]
public async validateRelationshipsByIds(
template: TypeModel,
groups: DirectionToRelatedEntityArrayMap,
devices: DirectionToRelatedEntityArrayMap
): Promise<ValidateRelationshipsByIdsResult> {
logger.debug(
`schemaValidator.full.service validateRelationshipsByIds: in: template:${JSON.stringify(
template
)}, groups:${JSON.stringify(groups)}, devices:${JSON.stringify(devices)}`
);
ow(template, ow.object.nonEmpty);
// extrapolate the entity ids from the rels parameter to make our lives easier...
const extrapolateIds = (rels: RelatedEntityArrayMap, ids: string[]) => {
if ((Object.keys(rels || {}).length ?? 0) > 0) {
Object.values(rels).forEach((entities) =>
entities.forEach((entity) => ids.push(entity.id.toLowerCase()))
);
}
};
const groupPaths: string[] = [];
extrapolateIds(groups?.in, groupPaths);
extrapolateIds(groups?.out, groupPaths);
const deviceIds: string[] = [];
extrapolateIds(devices?.in, deviceIds);
extrapolateIds(devices?.out, deviceIds);
let isValid = true;
// retrieve the labels of entities to link, along with allowed relations
const groupLabelsFuture = this.groupsDao.getLabels(groupPaths);
const deviceLabelsFuture = this.devicesDao.getLabels(deviceIds);
const [groupLabels, deviceLabels] = await Promise.all([
groupLabelsFuture,
deviceLabelsFuture,
]);
// ensure the provided entity ids are valid
const validatedGroupPaths = Object.keys(groupLabels || {});
const invalidGroupPaths = groupPaths.filter((path) => !validatedGroupPaths.includes(path));
if (invalidGroupPaths.length > 0) {
isValid = false;
}
const validatedDeviceIds = Object.keys(deviceLabels || {});
const invalidDeviceIds = deviceIds.filter((id) => !validatedDeviceIds.includes(id));
if (invalidDeviceIds.length > 0) {
isValid = false;
}
// verify that the attempted relationships are valid
const invalidRelations: { [relation: string]: string[] } = {};
const validateIncomingRelations = (
rels: RelatedEntityArrayMap,
labels: EntityTypeMap
): void => {
if (Object.keys(rels || {}).length === 0) return;
for (const [relation, entities] of Object.entries(rels)) {
for (const entity of entities) {
const label = labels[entity.id.toLowerCase()]?.filter(
(label) => label !== 'group' && label !== 'device'
)?.[0];
if (
label === undefined ||
!template.schema.relations.incomingIncludes(relation, label)
) {
if (invalidRelations[relation] === undefined) {
invalidRelations[relation] = [];
}
invalidRelations[relation].push(label);
isValid = false;
}
}
}
};
const validateOutgoingRelations = (
rels: RelatedEntityArrayMap,
labels: EntityTypeMap
): void => {
if (Object.keys(rels || {}).length === 0) return;
for (const [relation, entities] of Object.entries(rels)) {
logger.debug(
`schemaValidator.full.service validateRelationshipsByIds: ***: relation: ${relation}, entities: ${JSON.stringify(
entities
)}`
);
for (const entity of entities) {
logger.debug(
`schemaValidator.full.service validateRelationshipsByIds: ***: entity: ${JSON.stringify(
entity
)}`
);
const label = labels[entity.id.toLowerCase()]?.filter(
(label) => label !== 'group' && label !== 'device'
)?.[0];
logger.debug(
`schemaValidator.full.service validateRelationshipsByIds: ***: label: ${JSON.stringify(
label
)}`
);
if (
label === undefined ||
!template.schema.relations.outgoingIncludes(relation, label)
) {
if (invalidRelations[relation] === undefined) {
invalidRelations[relation] = [];
}
invalidRelations[relation].push(label);
isValid = false;
logger.debug(
`schemaValidator.full.service validateRelationshipsByIds: ***: updated invalidRelations: ${JSON.stringify(
invalidRelations
)}`
);
}
}
}
};
validateIncomingRelations(groups?.in, groupLabels);
validateOutgoingRelations(groups?.out, groupLabels);
validateIncomingRelations(devices?.in, deviceLabels);
validateOutgoingRelations(devices?.out, deviceLabels);
const response = {
groupLabels,
deviceLabels,
invalidGroupPaths,
invalidDeviceIds,
invalidRelations,
isValid,
};
logger.debug(
`schemaValidator.full.service validateRelationshipsByIds: exit: ${JSON.stringify(
response
)}`
);
return response;
}