feat: normalize and validate component model structure
This commit is contained in:
109
src/component-models/structure.normalizer.ts
Normal file
109
src/component-models/structure.normalizer.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import type { ComponentModelStructure } from '../shared/types/inventory';
|
||||
|
||||
type InputValue = Record<string, unknown> | null | undefined;
|
||||
|
||||
const toArray = (value: unknown): unknown[] => {
|
||||
if (Array.isArray(value)) {
|
||||
return value;
|
||||
}
|
||||
if (value === undefined || value === null) {
|
||||
return [];
|
||||
}
|
||||
return [value];
|
||||
};
|
||||
|
||||
const sanitizeRole = (role: unknown): string | undefined => {
|
||||
if (role === undefined || role === null) {
|
||||
return undefined;
|
||||
}
|
||||
const stringValue = String(role).trim();
|
||||
return stringValue ? stringValue : undefined;
|
||||
};
|
||||
|
||||
const sanitizeAlias = (alias: unknown): string | undefined => {
|
||||
if (alias === undefined || alias === null) {
|
||||
return undefined;
|
||||
}
|
||||
const stringValue = String(alias).trim();
|
||||
return stringValue ? stringValue : undefined;
|
||||
};
|
||||
|
||||
const ensureString = (value: unknown): string => String(value ?? '');
|
||||
|
||||
export function normalizeComponentModelStructure(
|
||||
input: unknown,
|
||||
): ComponentModelStructure {
|
||||
const structure = (input ?? {}) as InputValue;
|
||||
|
||||
const pieces = toArray((structure as any)?.pieces).map((piece) => {
|
||||
const candidate = piece as Record<string, unknown> | null | undefined;
|
||||
if (candidate?.familyCode) {
|
||||
return {
|
||||
familyCode: ensureString(candidate.familyCode).trim() || 'UNKNOWN',
|
||||
role: sanitizeRole(candidate.role),
|
||||
} as ComponentModelStructure['pieces'][number];
|
||||
}
|
||||
if (candidate?.typePieceId) {
|
||||
return {
|
||||
typePieceId: ensureString(candidate.typePieceId).trim() || 'UNKNOWN',
|
||||
role: sanitizeRole(candidate.role),
|
||||
} as ComponentModelStructure['pieces'][number];
|
||||
}
|
||||
|
||||
return {
|
||||
familyCode:
|
||||
ensureString(
|
||||
candidate?.familyCode ?? candidate?.name ?? candidate?.typePieceLabel ?? 'UNKNOWN',
|
||||
).trim() || 'UNKNOWN',
|
||||
role: sanitizeRole(candidate?.role),
|
||||
} as ComponentModelStructure['pieces'][number];
|
||||
});
|
||||
|
||||
const customFields = toArray((structure as any)?.customFields).map((field) => {
|
||||
const candidate = field as Record<string, unknown> | null | undefined;
|
||||
const key = ensureString(candidate?.key ?? candidate?.name ?? 'unknown').trim();
|
||||
|
||||
return {
|
||||
key: key || 'unknown',
|
||||
value: candidate?.value ?? null,
|
||||
};
|
||||
});
|
||||
|
||||
const rawSubcomponents = toArray(
|
||||
(structure as any)?.subcomponents ?? (structure as any)?.subComponents,
|
||||
);
|
||||
|
||||
const subcomponents = rawSubcomponents.map((subcomponent) => {
|
||||
const candidate = subcomponent as Record<string, unknown> | null | undefined;
|
||||
|
||||
if (candidate?.modelId) {
|
||||
return {
|
||||
modelId: ensureString(candidate.modelId).trim() || 'UNKNOWN',
|
||||
alias: sanitizeAlias(candidate?.alias ?? candidate?.name),
|
||||
} as ComponentModelStructure['subcomponents'][number];
|
||||
}
|
||||
if (candidate?.familyCode) {
|
||||
return {
|
||||
familyCode: ensureString(candidate.familyCode).trim() || 'UNKNOWN',
|
||||
alias: sanitizeAlias(candidate?.alias ?? candidate?.name),
|
||||
} as ComponentModelStructure['subcomponents'][number];
|
||||
}
|
||||
if (candidate?.typeComposantId) {
|
||||
return {
|
||||
typeComposantId: ensureString(candidate.typeComposantId).trim() || 'UNKNOWN',
|
||||
alias: sanitizeAlias(candidate?.alias ?? candidate?.name),
|
||||
} as ComponentModelStructure['subcomponents'][number];
|
||||
}
|
||||
|
||||
return {
|
||||
familyCode: ensureString(candidate?.name ?? 'UNKNOWN').trim() || 'UNKNOWN',
|
||||
alias: sanitizeAlias(candidate?.alias ?? candidate?.name),
|
||||
} as ComponentModelStructure['subcomponents'][number];
|
||||
});
|
||||
|
||||
return {
|
||||
pieces,
|
||||
customFields,
|
||||
subcomponents,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user