Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | import * as crypto from "crypto";
import type { HistoryEntry, SegmentKey } from "@featurevisor/types";
import { Dependencies } from "../dependencies";
export interface DuplicateSegmentsOptions {
authors?: boolean;
}
export interface DuplicateSegmentsResult {
segments: SegmentKey[];
authors?: string[];
}
export async function findDuplicateSegments(
deps: Dependencies,
options: DuplicateSegmentsOptions = {},
): Promise<DuplicateSegmentsResult[]> {
const { datasource } = deps;
const segments = await datasource.listSegments();
const segmentsWithHash: { segmentKey: SegmentKey; hash: string }[] = [];
for (const segmentKey of segments) {
const segment = await datasource.readSegment(segmentKey);
const conditions = JSON.stringify(segment.conditions);
const hash = crypto.createHash("sha256").update(conditions).digest("hex");
segmentsWithHash.push({
segmentKey,
hash,
});
}
const groupedSegments: { [hash: string]: SegmentKey[] } = segmentsWithHash.reduce(
(acc, { segmentKey, hash }) => {
if (!acc[hash]) {
acc[hash] = [];
}
acc[hash].push(segmentKey);
return acc;
},
{},
);
const duplicateSegments = Object.values(groupedSegments).filter(
(segmentKeys) => segmentKeys.length > 1,
);
const result: DuplicateSegmentsResult[] = [];
for (const segmentKeys of duplicateSegments) {
const entry: DuplicateSegmentsResult = {
segments: segmentKeys,
};
if (options.authors) {
const historyEntries: HistoryEntry[] = [];
for (const segmentKey of segmentKeys) {
const entries = await datasource.listHistoryEntries("segment", segmentKey);
entries.forEach((entry) => {
historyEntries.push(entry);
});
}
const authors = Array.from(new Set(historyEntries.map((entry) => entry.author)));
entry.authors = authors;
}
result.push(entry);
}
return result;
}
|