Persist Revit CSV configuration

This commit is contained in:
Julian Appel 2026-08-02 16:33:18 +02:00
parent da689af518
commit 219da5ec3b
22 changed files with 2508 additions and 27 deletions

View file

@ -27,6 +27,7 @@ export function assertExternalCsvConfiguration(
if (!isRecord(value)) {
throw new Error("External CSV configuration must be an object.");
}
assertExactKeyCount(value, 9, "External CSV configuration");
if (value.schemaVersion !== externalCsvConfigurationSchemaVersion) {
throw new Error("Unsupported external CSV configuration schema version.");
}
@ -47,6 +48,7 @@ export function assertExternalCsvConfiguration(
if (!isRecord(value.columns)) {
throw new Error("External CSV columns must be an object.");
}
assertExactKeyCount(value.columns, 8, "External CSV columns");
const mappedColumns = new Set<string>();
for (const key of requiredColumnKeys) {
const columnName = assertTrimmedString(value.columns[key], `columns.${key}`);
@ -74,6 +76,7 @@ export function assertExternalCsvConfiguration(
if (!isRecord(mapping)) {
throw new Error(`additionalSourceMappings.${index} must be an object.`);
}
assertExactKeyCount(mapping, 2, `additionalSourceMappings.${index}`);
const sourceColumn = assertTrimmedString(
mapping.sourceColumn,
`additionalSourceMappings.${index}.sourceColumn`
@ -100,6 +103,7 @@ export function assertExternalCsvConfiguration(
if (!isRecord(rule)) {
throw new Error(`familyTypeRules.${index} must be an object.`);
}
assertExactKeyCount(rule, 6, `familyTypeRules.${index}`);
const exactFamilyAndType = assertTrimmedString(
rule.exactFamilyAndType,
`familyTypeRules.${index}.exactFamilyAndType`
@ -152,9 +156,11 @@ function assertQuantityRule(value: unknown, index: number): asserts value is Ext
throw new Error(`familyTypeRules.${index}.quantityRule must be an object.`);
}
if (value.kind === "mapped-column") {
assertExactKeyCount(value, 1, `familyTypeRules.${index}.quantityRule`);
return;
}
if (value.kind === "fixed") {
assertExactKeyCount(value, 2, `familyTypeRules.${index}.quantityRule`);
assertPositiveFiniteNumber(value.quantity, `familyTypeRules.${index}.quantityRule.quantity`);
return;
}
@ -172,9 +178,11 @@ function assertDisplayNameSuggestion(
throw new Error(`familyTypeRules.${index}.displayNameSuggestion must be an object or null.`);
}
if (value.kind === "selection-marker" || value.kind === "family-and-type") {
assertExactKeyCount(value, 1, `familyTypeRules.${index}.displayNameSuggestion`);
return;
}
if (value.kind === "fixed") {
assertExactKeyCount(value, 2, `familyTypeRules.${index}.displayNameSuggestion`);
assertTrimmedString(value.value, `familyTypeRules.${index}.displayNameSuggestion.value`);
return;
}
@ -197,3 +205,9 @@ function assertTrimmedString(value: unknown, field: string) {
function isRecord(value: unknown): value is Record<string, unknown> {
return value !== null && typeof value === "object" && !Array.isArray(value);
}
function assertExactKeyCount(value: Record<string, unknown>, count: number, field: string) {
if (Object.keys(value).length !== count) {
throw new Error(`${field} contains unknown or missing fields.`);
}
}