1import { dedupSources } from './Dedup';
2import type { Fingerprint, FingerprintSource, Options } from './Fingerprint.types';
3import { normalizeOptions } 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 = normalizeOptions(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  const result: FingerprintSource[] = newFingerprint.sources.filter((newItem) => {
46    return !fingerprint.sources.find(
47      (item) => item.type === newItem.type && item.hash === newItem.hash
48    );
49  });
50  return result;
51}
52