forked from jappel/leistungsbilanz-ts
Add Revit CSV preview API
This commit is contained in:
parent
219da5ec3b
commit
caa6caf99f
14 changed files with 437 additions and 3 deletions
91
src/external-model/application/external-csv-preview.ts
Normal file
91
src/external-model/application/external-csv-preview.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import { createHash } from "node:crypto";
|
||||
import type { ExternalCsvConfiguration } from "../csv/external-csv-contracts.js";
|
||||
import { parseExternalCsv } from "../csv/external-csv-transport.js";
|
||||
|
||||
export interface ExternalCsvPreviewObject {
|
||||
rowNumber: number;
|
||||
ifcGuid: string;
|
||||
roomNumber: string;
|
||||
roomName: string;
|
||||
familyAndType: string;
|
||||
selectionMarker: string;
|
||||
circuitIdentifier: string;
|
||||
power: string;
|
||||
quantity: string | null;
|
||||
additionalSourceValues: Record<string, string>;
|
||||
}
|
||||
|
||||
export interface ExternalCsvPreview {
|
||||
fileName: string;
|
||||
byteLength: number;
|
||||
sha256: string;
|
||||
dialect: ReturnType<typeof parseExternalCsv>["dialect"];
|
||||
headerRowNumber: number;
|
||||
headerColumns: string[];
|
||||
rowCount: number;
|
||||
objectCount: number;
|
||||
passthroughCount: number;
|
||||
nonEmptyPassthroughCount: number;
|
||||
suspectObjectCount: number;
|
||||
objects: ExternalCsvPreviewObject[];
|
||||
suspectRowNumbers: number[];
|
||||
}
|
||||
|
||||
export function createExternalCsvPreview(input: {
|
||||
fileName: string;
|
||||
bytes: Uint8Array;
|
||||
configuration: ExternalCsvConfiguration;
|
||||
}): ExternalCsvPreview {
|
||||
const document = parseExternalCsv(input.bytes, input.configuration);
|
||||
const header = document.rows[document.headerRowIndex];
|
||||
const headerIndex = new Map(
|
||||
header.cells.map((cell, index) => [cell.value, index])
|
||||
);
|
||||
const valueAt = (row: (typeof document.rows)[number], column: string) =>
|
||||
row.cells[headerIndex.get(column)!]?.value ?? "";
|
||||
const objects = document.rows
|
||||
.filter((row) => row.classification === "object")
|
||||
.map((row): ExternalCsvPreviewObject => ({
|
||||
rowNumber: row.index + 1,
|
||||
ifcGuid: valueAt(row, input.configuration.columns.ifcGuid),
|
||||
roomNumber: valueAt(row, input.configuration.columns.roomNumber),
|
||||
roomName: valueAt(row, input.configuration.columns.roomName),
|
||||
familyAndType: valueAt(row, input.configuration.columns.familyAndType),
|
||||
selectionMarker: valueAt(row, input.configuration.columns.selectionMarker),
|
||||
circuitIdentifier: valueAt(row, input.configuration.columns.circuitIdentifier),
|
||||
power: valueAt(row, input.configuration.columns.power),
|
||||
quantity:
|
||||
input.configuration.columns.quantity === null
|
||||
? null
|
||||
: valueAt(row, input.configuration.columns.quantity),
|
||||
additionalSourceValues: Object.fromEntries(
|
||||
input.configuration.additionalSourceMappings.map((mapping) => [
|
||||
mapping.targetField,
|
||||
valueAt(row, mapping.sourceColumn),
|
||||
])
|
||||
),
|
||||
}));
|
||||
const passthroughRows = document.rows.filter(
|
||||
(row) => row.classification === "passthrough"
|
||||
);
|
||||
const suspectRows = document.rows.filter(
|
||||
(row) => row.classification === "suspect-object"
|
||||
);
|
||||
return {
|
||||
fileName: input.fileName,
|
||||
byteLength: input.bytes.byteLength,
|
||||
sha256: createHash("sha256").update(input.bytes).digest("hex"),
|
||||
dialect: document.dialect,
|
||||
headerRowNumber: document.headerRowIndex + 1,
|
||||
headerColumns: header.cells.map((cell) => cell.value),
|
||||
rowCount: document.rows.length,
|
||||
objectCount: objects.length,
|
||||
passthroughCount: passthroughRows.length,
|
||||
nonEmptyPassthroughCount: passthroughRows.filter((row) =>
|
||||
row.cells.some((cell) => cell.value !== "")
|
||||
).length,
|
||||
suspectObjectCount: suspectRows.length,
|
||||
objects,
|
||||
suspectRowNumbers: suspectRows.map((row) => row.index + 1),
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue