lockfile-hasher 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,5 +15,13 @@ npm install lockfile-hasher
15
15
  ```js
16
16
  import { generateCombinedLockFileHash } from 'lockfile-hasher';
17
17
 
18
- const combinedHash = generateCombinedLockfileHash(pathToRepositoryRoot);
18
+ const combinedHash = generateCombinedLockFileHash(pathToRepositoryRoot);
19
+ ```
20
+
21
+ Alternatively, you can use the default export. This allows for easier mocking, since hashing lockfiles is an expensive operation that you really don't want to do during unit tests:
22
+
23
+ ```js
24
+ import lockfileHasher from 'lockfile-hasher';
25
+
26
+ const combinedHash = lockfileHasher.generateCombinedLockFileHash(pathToRepositoryRoot);
19
27
  ```
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Generate a combined hash of all lock files in a repo.
3
+ * @param {string} rootPath - Root path of the repository
4
+ * @returns {Promise<string>} - Combined hash string
5
+ */
6
+ export declare function generateCombinedLockFileHash(rootPath: string): Promise<string>;
7
+ declare const _default: {
8
+ generateCombinedLockFileHash: typeof generateCombinedLockFileHash;
9
+ };
10
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,35 @@
1
+ import crypto from 'node:crypto';
2
+ import { readFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { glob } from 'glob';
5
+ const GLOB_PATTERNS = ['**/package-lock.json', '**/yarn.lock', '**/pnpm-lock.yaml'];
6
+ const GLOB_OPTIONS = { ignore: '**/node_modules/**' };
7
+ /**
8
+ * Generate a combined hash of all lock files in a repo.
9
+ * @param {string} rootPath - Root path of the repository
10
+ * @returns {Promise<string>} - Combined hash string
11
+ */
12
+ export async function generateCombinedLockFileHash(rootPath) {
13
+ const files = await Promise.all(GLOB_PATTERNS.map((pattern) => glob(path.join(rootPath, pattern), GLOB_OPTIONS))).then((results) => results.flat());
14
+ const fileContents = await Promise.all(files.map((file) => readFile(file)));
15
+ // Generate hash for each file
16
+ const hashesMap = {};
17
+ files.forEach((file, i) => {
18
+ const relativePath = path.relative(rootPath, file);
19
+ const fileContent = fileContents[i];
20
+ const hash = crypto.createHash('sha256').update(fileContent).digest('hex');
21
+ hashesMap[relativePath] = hash;
22
+ });
23
+ // Sort the entries to ensure consistent hash
24
+ const sortedEntries = Object.entries(hashesMap).sort(([pathA], [pathB]) => {
25
+ return pathA.localeCompare(pathB);
26
+ });
27
+ // Create a string representation of all hashes
28
+ const combinedString = sortedEntries.map(([relPath, hash]) => `${relPath}:${hash}`).join('|');
29
+ // Generate a new hash from the combined string
30
+ return crypto.createHash('sha256').update(combinedString).digest('hex');
31
+ }
32
+ export default {
33
+ generateCombinedLockFileHash,
34
+ };
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,aAAa,GAAG,CAAC,sBAAsB,EAAE,cAAc,EAAE,mBAAmB,CAAC,CAAC;AACpF,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;AAEtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,QAAgB;IACjE,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CACjF,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE5E,8BAA8B;IAC9B,MAAM,SAAS,GAA2B,EAAE,CAAC;IAE7C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACxB,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3E,SAAS,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,6CAA6C;IAC7C,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE;QACxE,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,+CAA+C;IAC/C,MAAM,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE9F,+CAA+C;IAC/C,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1E,CAAC;AAED,eAAe;IACb,4BAA4B;CAC7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lockfile-hasher",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Generates a combined hash of all the lockfiles in a repository",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  "scripts": {
34
34
  "build": "rm -rf dist && tsc",
35
35
  "check-format": "biome check .",
36
- "ci": "pnpm run test && pnpm run check-format",
36
+ "ci": "pnpm run test && pnpm run check-format && pnpm run build",
37
37
  "format": "biome check --write .",
38
38
  "test": "node --experimental-strip-types --test"
39
39
  }