1import { dedupSources } from './Dedup';
2import type { Fingerprint, FingerprintSource, Options } from './Fingerprint.types';
3import { normalizeOptionsAsync } from './Options';
4import { sortSources } from './Sort';
5import { createFingerprintFromSourcesAsync } from './hash/Hash';
6import { getHashSourcesAsync } from './sourcer/Sourcer';
7
8/**
9 * Create a fingerprint from project
10 */
11export async function createFingerprintAsync(
12  projectRoot: string,
13  options?: Options
14): Promise<Fingerprint> {
15  const opts = await normalizeOptionsAsync(projectRoot, options);
16  const sources = await getHashSourcesAsync(projectRoot, opts);
17  const normalizedSources = sortSources(dedupSources(sources, projectRoot));
18  const fingerprint = await createFingerprintFromSourcesAsync(normalizedSources, projectRoot, opts);
19  return fingerprint;
20}
21
22/**
23 * Create a native hash value from project
24 */
25export async function createProjectHashAsync(
26  projectRoot: string,
27  options?: Options
28): Promise<string> {
29  const fingerprint = await createFingerprintAsync(projectRoot, options);
30  return fingerprint.hash;
31}
32
33/**
34 * Differentiate given `fingerprint` with the current project fingerprint state
35 */
36export async function diffFingerprintChangesAsync(
37  fingerprint: Fingerprint,
38  projectRoot: string,
39  options?: Options
40): Promise<FingerprintSource[]> {
41  const newFingerprint = await createFingerprintAsync(projectRoot, options);
42  if (fingerprint.hash === newFingerprint.hash) {
43    return [];
44  }
45  return diffFingerprints(fingerprint, newFingerprint);
46}
47
48/**
49 * Differentiate two fingerprints
50 */
51export function diffFingerprints(
52  fingerprint1: Fingerprint,
53  fingerprint2: Fingerprint
54): FingerprintSource[] {
55  return fingerprint2.sources.filter((newItem) => {
56    return !fingerprint1.sources.find(
57      (item) => item.type === newItem.type && item.hash === newItem.hash
58    );
59  });
60}
61