chore: import DH V2 D5.6.4 production baseline
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
import {
|
||||
AssetAttributeDataType,
|
||||
AssetAttributeDefinition,
|
||||
} from '../database/entities';
|
||||
|
||||
export interface NormalizedAttributeValue {
|
||||
definitionId: string;
|
||||
value: unknown;
|
||||
}
|
||||
|
||||
function invalidAttribute(message: string, definitionId?: string): never {
|
||||
throw new BadRequestException({
|
||||
code: 'INVALID_ASSET_ATTRIBUTE',
|
||||
message,
|
||||
...(definitionId ? { definitionId } : {}),
|
||||
});
|
||||
}
|
||||
|
||||
function isMissing(value: unknown): boolean {
|
||||
return value === undefined || value === null || value === '';
|
||||
}
|
||||
|
||||
function isValidCalendarDate(value: string): boolean {
|
||||
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return false;
|
||||
const [year, month, day] = value.split('-').map(Number);
|
||||
const parsed = new Date(Date.UTC(year!, month! - 1, day));
|
||||
return (
|
||||
parsed.getUTCFullYear() === year &&
|
||||
parsed.getUTCMonth() === month! - 1 &&
|
||||
parsed.getUTCDate() === day
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeValue(
|
||||
definition: AssetAttributeDefinition,
|
||||
value: unknown,
|
||||
): unknown {
|
||||
switch (definition.dataType) {
|
||||
case AssetAttributeDataType.TEXT:
|
||||
if (typeof value !== 'string' || value.length > 4000) {
|
||||
return invalidAttribute(
|
||||
`El atributo ${definition.name} debe ser un texto de hasta 4000 caracteres`,
|
||||
definition.id,
|
||||
);
|
||||
}
|
||||
return value.trim();
|
||||
|
||||
case AssetAttributeDataType.NUMBER:
|
||||
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
||||
return invalidAttribute(
|
||||
`El atributo ${definition.name} debe ser numérico`,
|
||||
definition.id,
|
||||
);
|
||||
}
|
||||
return value;
|
||||
|
||||
case AssetAttributeDataType.BOOLEAN:
|
||||
if (typeof value !== 'boolean') {
|
||||
return invalidAttribute(
|
||||
`El atributo ${definition.name} debe ser verdadero o falso`,
|
||||
definition.id,
|
||||
);
|
||||
}
|
||||
return value;
|
||||
|
||||
case AssetAttributeDataType.DATE:
|
||||
if (typeof value !== 'string' || !isValidCalendarDate(value)) {
|
||||
return invalidAttribute(
|
||||
`El atributo ${definition.name} debe ser una fecha válida`,
|
||||
definition.id,
|
||||
);
|
||||
}
|
||||
return value;
|
||||
|
||||
case AssetAttributeDataType.DATETIME:
|
||||
if (
|
||||
typeof value !== 'string' ||
|
||||
!value.trim() ||
|
||||
!Number.isFinite(Date.parse(value))
|
||||
) {
|
||||
return invalidAttribute(
|
||||
`El atributo ${definition.name} debe ser una fecha y hora válida`,
|
||||
definition.id,
|
||||
);
|
||||
}
|
||||
return new Date(value).toISOString();
|
||||
|
||||
case AssetAttributeDataType.SELECT: {
|
||||
const options = definition.options ?? [];
|
||||
if (typeof value !== 'string' || !options.includes(value)) {
|
||||
return invalidAttribute(
|
||||
`El atributo ${definition.name} no contiene una opción válida`,
|
||||
definition.id,
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function validateAssetAttributeValues(
|
||||
definitions: AssetAttributeDefinition[],
|
||||
values: Record<string, unknown>,
|
||||
): NormalizedAttributeValue[] {
|
||||
const activeDefinitions = definitions.filter((definition) => definition.isActive);
|
||||
const byId = new Map(activeDefinitions.map((definition) => [definition.id, definition]));
|
||||
|
||||
for (const definitionId of Object.keys(values)) {
|
||||
if (!byId.has(definitionId)) {
|
||||
invalidAttribute('Se recibió un atributo que no pertenece al tipo de activo', definitionId);
|
||||
}
|
||||
}
|
||||
|
||||
const normalized: NormalizedAttributeValue[] = [];
|
||||
for (const definition of activeDefinitions) {
|
||||
const value = values[definition.id];
|
||||
if (isMissing(value)) {
|
||||
if (definition.isRequired) {
|
||||
invalidAttribute(`El atributo ${definition.name} es obligatorio`, definition.id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
normalized.push({
|
||||
definitionId: definition.id,
|
||||
value: normalizeValue(definition, value),
|
||||
});
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
Reference in New Issue
Block a user