@tractorcow/beefup 0.0.0 → 1.0.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.
Files changed (165) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +108 -0
  3. package/dist/__tests__/with-safe-chain-stubs.d.ts +5 -0
  4. package/dist/__tests__/with-safe-chain-stubs.js +25 -0
  5. package/dist/__tests__/with-safe-chain-stubs.js.map +1 -0
  6. package/dist/bin.d.ts +2 -0
  7. package/dist/bin.js +6 -0
  8. package/dist/bin.js.map +1 -0
  9. package/dist/cli/args.d.ts +18 -0
  10. package/dist/cli/args.js +88 -0
  11. package/dist/cli/args.js.map +1 -0
  12. package/dist/cli/main.d.ts +4 -0
  13. package/dist/cli/main.js +81 -0
  14. package/dist/cli/main.js.map +1 -0
  15. package/dist/commands/accept.d.ts +16 -0
  16. package/dist/commands/accept.js +47 -0
  17. package/dist/commands/accept.js.map +1 -0
  18. package/dist/commands/report.d.ts +19 -0
  19. package/dist/commands/report.js +151 -0
  20. package/dist/commands/report.js.map +1 -0
  21. package/dist/commands/stage.d.ts +16 -0
  22. package/dist/commands/stage.js +60 -0
  23. package/dist/commands/stage.js.map +1 -0
  24. package/dist/config/load.d.ts +6 -0
  25. package/dist/config/load.js +103 -0
  26. package/dist/config/load.js.map +1 -0
  27. package/dist/config/types.d.ts +75 -0
  28. package/dist/config/types.js +68 -0
  29. package/dist/config/types.js.map +1 -0
  30. package/dist/diff/diff.d.ts +21 -0
  31. package/dist/diff/diff.js +132 -0
  32. package/dist/diff/diff.js.map +1 -0
  33. package/dist/diff/group.d.ts +5 -0
  34. package/dist/diff/group.js +24 -0
  35. package/dist/diff/group.js.map +1 -0
  36. package/dist/diff/types.d.ts +37 -0
  37. package/dist/diff/types.js +7 -0
  38. package/dist/diff/types.js.map +1 -0
  39. package/dist/errors.d.ts +10 -0
  40. package/dist/errors.js +15 -0
  41. package/dist/errors.js.map +1 -0
  42. package/dist/fsutil.d.ts +20 -0
  43. package/dist/fsutil.js +43 -0
  44. package/dist/fsutil.js.map +1 -0
  45. package/dist/lockfile/locked.d.ts +9 -0
  46. package/dist/lockfile/locked.js +15 -0
  47. package/dist/lockfile/locked.js.map +1 -0
  48. package/dist/lockfile/npm.d.ts +15 -0
  49. package/dist/lockfile/npm.js +152 -0
  50. package/dist/lockfile/npm.js.map +1 -0
  51. package/dist/lockfile/pnpm.d.ts +27 -0
  52. package/dist/lockfile/pnpm.js +155 -0
  53. package/dist/lockfile/pnpm.js.map +1 -0
  54. package/dist/lockfile/resolve.d.ts +10 -0
  55. package/dist/lockfile/resolve.js +20 -0
  56. package/dist/lockfile/resolve.js.map +1 -0
  57. package/dist/lockfile/types.d.ts +49 -0
  58. package/dist/lockfile/types.js +2 -0
  59. package/dist/lockfile/types.js.map +1 -0
  60. package/dist/pm/cve-lite-bin.d.ts +5 -0
  61. package/dist/pm/cve-lite-bin.js +36 -0
  62. package/dist/pm/cve-lite-bin.js.map +1 -0
  63. package/dist/pm/install.d.ts +24 -0
  64. package/dist/pm/install.js +30 -0
  65. package/dist/pm/install.js.map +1 -0
  66. package/dist/pm/runner.d.ts +17 -0
  67. package/dist/pm/runner.js +27 -0
  68. package/dist/pm/runner.js.map +1 -0
  69. package/dist/pm/safe-chain.d.ts +17 -0
  70. package/dist/pm/safe-chain.js +65 -0
  71. package/dist/pm/safe-chain.js.map +1 -0
  72. package/dist/pm/update.d.ts +16 -0
  73. package/dist/pm/update.js +25 -0
  74. package/dist/pm/update.js.map +1 -0
  75. package/dist/policy/alignment.d.ts +13 -0
  76. package/dist/policy/alignment.js +171 -0
  77. package/dist/policy/alignment.js.map +1 -0
  78. package/dist/policy/evaluate.d.ts +19 -0
  79. package/dist/policy/evaluate.js +75 -0
  80. package/dist/policy/evaluate.js.map +1 -0
  81. package/dist/policy/overrides.d.ts +42 -0
  82. package/dist/policy/overrides.js +358 -0
  83. package/dist/policy/overrides.js.map +1 -0
  84. package/dist/policy/ranges.d.ts +13 -0
  85. package/dist/policy/ranges.js +58 -0
  86. package/dist/policy/ranges.js.map +1 -0
  87. package/dist/project/collect.d.ts +15 -0
  88. package/dist/project/collect.js +60 -0
  89. package/dist/project/collect.js.map +1 -0
  90. package/dist/project/detect.d.ts +5 -0
  91. package/dist/project/detect.js +76 -0
  92. package/dist/project/detect.js.map +1 -0
  93. package/dist/project/direct-deps.d.ts +7 -0
  94. package/dist/project/direct-deps.js +28 -0
  95. package/dist/project/direct-deps.js.map +1 -0
  96. package/dist/project/package-json.d.ts +20 -0
  97. package/dist/project/package-json.js +6 -0
  98. package/dist/project/package-json.js.map +1 -0
  99. package/dist/project/paths.d.ts +31 -0
  100. package/dist/project/paths.js +45 -0
  101. package/dist/project/paths.js.map +1 -0
  102. package/dist/project/types.d.ts +13 -0
  103. package/dist/project/types.js +6 -0
  104. package/dist/project/types.js.map +1 -0
  105. package/dist/project/workspace.d.ts +14 -0
  106. package/dist/project/workspace.js +80 -0
  107. package/dist/project/workspace.js.map +1 -0
  108. package/dist/report/ansi.d.ts +31 -0
  109. package/dist/report/ansi.js +59 -0
  110. package/dist/report/ansi.js.map +1 -0
  111. package/dist/report/html.d.ts +6 -0
  112. package/dist/report/html.js +260 -0
  113. package/dist/report/html.js.map +1 -0
  114. package/dist/report/markdown.d.ts +6 -0
  115. package/dist/report/markdown.js +234 -0
  116. package/dist/report/markdown.js.map +1 -0
  117. package/dist/report/shared.d.ts +25 -0
  118. package/dist/report/shared.js +32 -0
  119. package/dist/report/shared.js.map +1 -0
  120. package/dist/report/text.d.ts +10 -0
  121. package/dist/report/text.js +156 -0
  122. package/dist/report/text.js.map +1 -0
  123. package/dist/report/types.d.ts +20 -0
  124. package/dist/report/types.js +2 -0
  125. package/dist/report/types.js.map +1 -0
  126. package/dist/rewrite/constraints.d.ts +20 -0
  127. package/dist/rewrite/constraints.js +64 -0
  128. package/dist/rewrite/constraints.js.map +1 -0
  129. package/dist/rewrite/repin.d.ts +8 -0
  130. package/dist/rewrite/repin.js +28 -0
  131. package/dist/rewrite/repin.js.map +1 -0
  132. package/dist/rewrite/workspace.d.ts +14 -0
  133. package/dist/rewrite/workspace.js +40 -0
  134. package/dist/rewrite/workspace.js.map +1 -0
  135. package/dist/security/classify.d.ts +48 -0
  136. package/dist/security/classify.js +86 -0
  137. package/dist/security/classify.js.map +1 -0
  138. package/dist/security/cve-lite.d.ts +7 -0
  139. package/dist/security/cve-lite.js +78 -0
  140. package/dist/security/cve-lite.js.map +1 -0
  141. package/dist/security/npm-audit.d.ts +10 -0
  142. package/dist/security/npm-audit.js +65 -0
  143. package/dist/security/npm-audit.js.map +1 -0
  144. package/dist/security/refs.d.ts +63 -0
  145. package/dist/security/refs.js +218 -0
  146. package/dist/security/refs.js.map +1 -0
  147. package/dist/security/scan.d.ts +13 -0
  148. package/dist/security/scan.js +32 -0
  149. package/dist/security/scan.js.map +1 -0
  150. package/dist/strategy/git.d.ts +16 -0
  151. package/dist/strategy/git.js +92 -0
  152. package/dist/strategy/git.js.map +1 -0
  153. package/dist/strategy/index.d.ts +7 -0
  154. package/dist/strategy/index.js +13 -0
  155. package/dist/strategy/index.js.map +1 -0
  156. package/dist/strategy/inplace.d.ts +30 -0
  157. package/dist/strategy/inplace.js +77 -0
  158. package/dist/strategy/inplace.js.map +1 -0
  159. package/dist/strategy/types.d.ts +13 -0
  160. package/dist/strategy/types.js +2 -0
  161. package/dist/strategy/types.js.map +1 -0
  162. package/dist/strategy/worktree.d.ts +26 -0
  163. package/dist/strategy/worktree.js +74 -0
  164. package/dist/strategy/worktree.js.map +1 -0
  165. package/package.json +60 -4
package/dist/fsutil.js ADDED
@@ -0,0 +1,43 @@
1
+ import { constants } from "node:fs";
2
+ import { access, cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ /**
5
+ * Returns whether a filesystem path exists and is accessible.
6
+ */
7
+ export async function pathExists(target) {
8
+ try {
9
+ await access(target, constants.F_OK);
10
+ return true;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ /**
17
+ * Reads a UTF-8 JSON file and parses it as type T.
18
+ */
19
+ export async function readJsonFile(filePath) {
20
+ const content = await readFile(filePath, "utf8");
21
+ return JSON.parse(content);
22
+ }
23
+ /**
24
+ * Writes a value as pretty-printed JSON, creating parent directories as needed.
25
+ */
26
+ export async function writeJsonFile(filePath, value) {
27
+ await mkdir(path.dirname(filePath), { recursive: true });
28
+ await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
29
+ }
30
+ /**
31
+ * Copies a file to a destination path, creating parent directories as needed.
32
+ */
33
+ export async function copyFileTo(src, dest) {
34
+ await mkdir(path.dirname(dest), { recursive: true });
35
+ await cp(src, dest);
36
+ }
37
+ /**
38
+ * Removes a file or directory tree if it exists.
39
+ */
40
+ export async function removePath(target) {
41
+ await rm(target, { recursive: true, force: true });
42
+ }
43
+ //# sourceMappingURL=fsutil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fsutil.js","sourceRoot":"","sources":["../src/fsutil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,QAAgB;IACpD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,KAAc;IAClE,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,SAAS,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3E,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,IAAY;IACxD,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { type PackageManager } from "../project/types.js";
2
+ /**
3
+ * Reads a lockfile and returns direct dependency versions for one workspace importer.
4
+ */
5
+ export declare function lockedVersionsForImporter(options: {
6
+ lockfilePath: string;
7
+ packageManager: PackageManager;
8
+ importerDir: string;
9
+ }): Promise<Map<string, string>>;
@@ -0,0 +1,15 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { PackageManagers } from "../project/types.js";
3
+ import { lockedVersionsFromNpm, parseNpmLockfile } from "./npm.js";
4
+ import { lockedVersionsFromPnpm, parsePnpmLockfile } from "./pnpm.js";
5
+ /**
6
+ * Reads a lockfile and returns direct dependency versions for one workspace importer.
7
+ */
8
+ export async function lockedVersionsForImporter(options) {
9
+ const content = await readFile(options.lockfilePath, "utf8");
10
+ if (options.packageManager === PackageManagers.Npm) {
11
+ return lockedVersionsFromNpm(parseNpmLockfile(content), options.importerDir);
12
+ }
13
+ return lockedVersionsFromPnpm(parsePnpmLockfile(content), options.importerDir);
14
+ }
15
+ //# sourceMappingURL=locked.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locked.js","sourceRoot":"","sources":["../../src/lockfile/locked.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAuB,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEtE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAI/C;IACC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC7D,IAAI,OAAO,CAAC,cAAc,KAAK,eAAe,CAAC,GAAG,EAAE,CAAC;QACnD,OAAO,qBAAqB,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,sBAAsB,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;AACjF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { NpmLockfile, Resolution } from "./types.js";
2
+ /**
3
+ * Parses package-lock.json content into a typed lockfile object.
4
+ * Throws when the JSON is invalid.
5
+ */
6
+ export declare function parseNpmLockfile(content: string): NpmLockfile;
7
+ /**
8
+ * Reads and resolves an npm lockfile on disk into dependency and devDependency lists.
9
+ * Includes nested installs with their install paths as scopes.
10
+ */
11
+ export declare function resolveNpmLockfile(filePath: string): Promise<Resolution>;
12
+ /**
13
+ * Maps direct (non-nested) package names to locked versions for one npm importer path.
14
+ */
15
+ export declare function lockedVersionsFromNpm(lockfile: NpmLockfile, importerDir: string): Map<string, string>;
@@ -0,0 +1,152 @@
1
+ import { readFile } from "node:fs/promises";
2
+ /**
3
+ * Derives a package name from an npm `packages` key (including nested installs).
4
+ */
5
+ function packageNameFromPackagesKey(key) {
6
+ if (key === "") {
7
+ return null;
8
+ }
9
+ const marker = "node_modules/";
10
+ const index = key.lastIndexOf(marker);
11
+ if (index === -1) {
12
+ return null;
13
+ }
14
+ const name = key.slice(index + marker.length);
15
+ return name.length > 0 ? name : null;
16
+ }
17
+ /**
18
+ * Appends dependency entries from an npm lockfile `packages` map, including nested paths.
19
+ */
20
+ function extractFromPackagesMap(deps, dependencies, devDependencies) {
21
+ for (const [key, dep] of Object.entries(deps)) {
22
+ if (!dep || !dep.version) {
23
+ continue;
24
+ }
25
+ const packageName = packageNameFromPackagesKey(key);
26
+ if (!packageName) {
27
+ continue;
28
+ }
29
+ const info = {
30
+ name: packageName,
31
+ version: dep.version,
32
+ path: key,
33
+ };
34
+ if (dep.optional === true) {
35
+ info.optional = true;
36
+ }
37
+ if (dep.dev === true) {
38
+ devDependencies.push(info);
39
+ continue;
40
+ }
41
+ dependencies.push(info);
42
+ }
43
+ }
44
+ /**
45
+ * Recursively walks a lockfileVersion 1 dependency tree, recording each install path.
46
+ */
47
+ function extractVersion1Tree(deps, dependencies, devDependencies, parentPath, forceDev) {
48
+ for (const [name, dep] of Object.entries(deps)) {
49
+ if (!dep || !dep.version) {
50
+ continue;
51
+ }
52
+ const installPath = parentPath
53
+ ? `${parentPath}/node_modules/${name}`
54
+ : `node_modules/${name}`;
55
+ const info = {
56
+ name,
57
+ version: dep.version,
58
+ path: installPath,
59
+ };
60
+ if (dep.optional === true) {
61
+ info.optional = true;
62
+ }
63
+ if (forceDev || dep.dev === true) {
64
+ devDependencies.push(info);
65
+ }
66
+ else {
67
+ dependencies.push(info);
68
+ }
69
+ if (dep.dependencies) {
70
+ extractVersion1Tree(dep.dependencies, dependencies, devDependencies, installPath, forceDev || dep.dev === true);
71
+ }
72
+ }
73
+ }
74
+ /**
75
+ * Builds a Resolution from an npm lockfileVersion 1 `dependencies` layout.
76
+ */
77
+ function resolveVersion1(lockfile) {
78
+ const dependencies = [];
79
+ const devDependencies = [];
80
+ if (lockfile.dependencies) {
81
+ extractVersion1Tree(lockfile.dependencies, dependencies, devDependencies, "", false);
82
+ }
83
+ if (lockfile.devDependencies) {
84
+ extractVersion1Tree(lockfile.devDependencies, dependencies, devDependencies, "", true);
85
+ }
86
+ return { dependencies, devDependencies };
87
+ }
88
+ /**
89
+ * Builds a Resolution from an npm lockfileVersion 2/3 `packages` layout.
90
+ */
91
+ function resolveVersion2Or3(lockfile) {
92
+ const dependencies = [];
93
+ const devDependencies = [];
94
+ if (lockfile.packages) {
95
+ extractFromPackagesMap(lockfile.packages, dependencies, devDependencies);
96
+ }
97
+ return { dependencies, devDependencies };
98
+ }
99
+ /**
100
+ * Parses package-lock.json content into a typed lockfile object.
101
+ * Throws when the JSON is invalid.
102
+ */
103
+ export function parseNpmLockfile(content) {
104
+ try {
105
+ return JSON.parse(content);
106
+ }
107
+ catch (error) {
108
+ throw new Error(`Failed to parse package-lock.json: ${error instanceof Error ? error.message : String(error)}`);
109
+ }
110
+ }
111
+ /**
112
+ * Reads and resolves an npm lockfile on disk into dependency and devDependency lists.
113
+ * Includes nested installs with their install paths as scopes.
114
+ */
115
+ export async function resolveNpmLockfile(filePath) {
116
+ const parsed = parseNpmLockfile(await readFile(filePath, "utf8"));
117
+ const lockfileVersion = parsed.lockfileVersion ?? 1;
118
+ switch (lockfileVersion) {
119
+ case 1:
120
+ return resolveVersion1(parsed);
121
+ case 2:
122
+ case 3:
123
+ return resolveVersion2Or3(parsed);
124
+ default:
125
+ throw new Error(`Unsupported lockfileVersion: ${lockfileVersion}. Only versions 1, 2, and 3 are supported.`);
126
+ }
127
+ }
128
+ /**
129
+ * Maps direct (non-nested) package names to locked versions for one npm importer path.
130
+ */
131
+ export function lockedVersionsFromNpm(lockfile, importerDir) {
132
+ const locked = new Map();
133
+ const packages = lockfile.packages ?? {};
134
+ const prefix = importerDir === "." || importerDir === ""
135
+ ? "node_modules/"
136
+ : `${importerDir.replace(/\\/g, "/")}/node_modules/`;
137
+ for (const [key, meta] of Object.entries(packages)) {
138
+ if (!meta?.version) {
139
+ continue;
140
+ }
141
+ if (!key.startsWith(prefix)) {
142
+ continue;
143
+ }
144
+ const rest = key.slice(prefix.length);
145
+ if (rest.includes("/node_modules/")) {
146
+ continue;
147
+ }
148
+ locked.set(rest, meta.version);
149
+ }
150
+ return locked;
151
+ }
152
+ //# sourceMappingURL=npm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm.js","sourceRoot":"","sources":["../../src/lockfile/npm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { PnpmLockfile, Resolution } from "./types.js";
2
+ /**
3
+ * Parses a pnpm packages-map key into package name and optional embedded version.
4
+ */
5
+ declare function extractPackageInfoFromName(key: string): {
6
+ name: string;
7
+ version: string | null;
8
+ } | null;
9
+ /**
10
+ * Parses pnpm-lock.yaml content into a typed lockfile object.
11
+ * Throws when the YAML is not a valid object.
12
+ */
13
+ export declare function parsePnpmLockfile(content: string): PnpmLockfile;
14
+ /**
15
+ * Reads and resolves a pnpm lockfile on disk into dependency and devDependency lists.
16
+ * Each packages-map entry is a scoped install keyed by its lockfile path.
17
+ */
18
+ export declare function resolvePnpmLockfile(filePath: string): Promise<Resolution>;
19
+ /**
20
+ * Removes the peer-dependency suffix (parenthetical) from a pnpm version string.
21
+ */
22
+ export declare function stripPnpmPeerSuffix(value: string): string;
23
+ /**
24
+ * Maps direct dependency names to locked versions for one pnpm importer path.
25
+ */
26
+ export declare function lockedVersionsFromPnpm(lockfile: PnpmLockfile, importerDir: string): Map<string, string>;
27
+ export { extractPackageInfoFromName };
@@ -0,0 +1,155 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { parse as parseYaml } from "yaml";
3
+ /**
4
+ * Normalizes a pnpm package key, dropping nested node_modules paths.
5
+ */
6
+ function cleanPackageKey(key) {
7
+ const parts = key.split("/");
8
+ const nodeModulesIndex = parts.indexOf("node_modules");
9
+ if (nodeModulesIndex !== -1) {
10
+ const nodeModulesCount = parts.filter((part) => part === "node_modules").length;
11
+ if (nodeModulesCount !== 1) {
12
+ return null;
13
+ }
14
+ return parts.slice(nodeModulesIndex + 1).join("/");
15
+ }
16
+ return key;
17
+ }
18
+ /**
19
+ * Parses a pnpm packages-map key into package name and optional embedded version.
20
+ */
21
+ function extractPackageInfoFromName(key) {
22
+ const packageKey = cleanPackageKey(key);
23
+ if (!packageKey) {
24
+ return null;
25
+ }
26
+ let working = packageKey;
27
+ if (working.startsWith("/")) {
28
+ working = working.slice(1);
29
+ }
30
+ const paren = working.indexOf("(");
31
+ if (paren !== -1) {
32
+ working = working.slice(0, paren);
33
+ }
34
+ if (working.startsWith("@")) {
35
+ const lastAtIndex = working.lastIndexOf("@");
36
+ if (lastAtIndex <= 0) {
37
+ return { name: working, version: null };
38
+ }
39
+ return {
40
+ name: working.slice(0, lastAtIndex),
41
+ version: working.slice(lastAtIndex + 1),
42
+ };
43
+ }
44
+ const at = working.lastIndexOf("@");
45
+ if (at <= 0) {
46
+ return { name: working, version: null };
47
+ }
48
+ return {
49
+ name: working.slice(0, at),
50
+ version: working.slice(at + 1),
51
+ };
52
+ }
53
+ /**
54
+ * Parses pnpm-lock.yaml content into a typed lockfile object.
55
+ * Throws when the YAML is not a valid object.
56
+ */
57
+ export function parsePnpmLockfile(content) {
58
+ try {
59
+ const parsed = parseYaml(content);
60
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
61
+ throw new Error("Parsed YAML is not an object");
62
+ }
63
+ return parsed;
64
+ }
65
+ catch (error) {
66
+ throw new Error(`Failed to parse pnpm-lock.yaml: ${error instanceof Error ? error.message : String(error)}`);
67
+ }
68
+ }
69
+ /**
70
+ * Reads and resolves a pnpm lockfile on disk into dependency and devDependency lists.
71
+ * Each packages-map entry is a scoped install keyed by its lockfile path.
72
+ */
73
+ export async function resolvePnpmLockfile(filePath) {
74
+ const lockfile = parsePnpmLockfile(await readFile(filePath, "utf8"));
75
+ const dependencies = [];
76
+ const devDependencies = [];
77
+ if (lockfile.packages) {
78
+ for (const [key, pkg] of Object.entries(lockfile.packages)) {
79
+ if (!pkg || typeof pkg !== "object") {
80
+ continue;
81
+ }
82
+ const nameAndVersion = extractPackageInfoFromName(key);
83
+ if (!nameAndVersion) {
84
+ continue;
85
+ }
86
+ const version = typeof pkg.version === "string" ? pkg.version : nameAndVersion.version;
87
+ if (!version) {
88
+ continue;
89
+ }
90
+ const info = {
91
+ name: nameAndVersion.name,
92
+ version,
93
+ path: key,
94
+ };
95
+ if (pkg.optional === true) {
96
+ info.optional = true;
97
+ }
98
+ if (pkg.dev === true) {
99
+ devDependencies.push(info);
100
+ continue;
101
+ }
102
+ dependencies.push(info);
103
+ }
104
+ }
105
+ return { dependencies, devDependencies };
106
+ }
107
+ /**
108
+ * Removes the peer-dependency suffix (parenthetical) from a pnpm version string.
109
+ */
110
+ export function stripPnpmPeerSuffix(value) {
111
+ const paren = value.indexOf("(");
112
+ return paren === -1 ? value : value.slice(0, paren);
113
+ }
114
+ /**
115
+ * Extracts a concrete version from a pnpm importer dependency entry.
116
+ */
117
+ function importerVersion(value) {
118
+ if (typeof value === "string") {
119
+ return stripPnpmPeerSuffix(value);
120
+ }
121
+ if (value && typeof value.version === "string") {
122
+ return stripPnpmPeerSuffix(value.version);
123
+ }
124
+ return undefined;
125
+ }
126
+ /**
127
+ * Maps direct dependency names to locked versions for one pnpm importer path.
128
+ */
129
+ export function lockedVersionsFromPnpm(lockfile, importerDir) {
130
+ const locked = new Map();
131
+ const key = importerDir === "." ? "." : importerDir.replace(/\\/g, "/");
132
+ const importer = lockfile.importers?.[key];
133
+ if (!importer) {
134
+ return locked;
135
+ }
136
+ const buckets = [
137
+ importer.dependencies,
138
+ importer.devDependencies,
139
+ importer.optionalDependencies,
140
+ ];
141
+ for (const bucket of buckets) {
142
+ if (!bucket) {
143
+ continue;
144
+ }
145
+ for (const [name, info] of Object.entries(bucket)) {
146
+ const version = importerVersion(info);
147
+ if (version && !version.startsWith("link:") && !version.startsWith("file:")) {
148
+ locked.set(name, version);
149
+ }
150
+ }
151
+ }
152
+ return locked;
153
+ }
154
+ export { extractPackageInfoFromName };
155
+ //# sourceMappingURL=pnpm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pnpm.js","sourceRoot":"","sources":["../../src/lockfile/pnpm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type PackageManager } from "../project/types.js";
2
+ import type { Resolution } from "./types.js";
3
+ /**
4
+ * Resolves direct dependency versions from an npm or pnpm lockfile.
5
+ */
6
+ export declare function resolveLockfile(lockfilePath: string, packageManager: PackageManager): Promise<Resolution>;
7
+ /**
8
+ * Reads a UTF-8 text file from disk.
9
+ */
10
+ export declare function readText(filePath: string): Promise<string>;
@@ -0,0 +1,20 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { PackageManagers } from "../project/types.js";
3
+ import { resolveNpmLockfile } from "./npm.js";
4
+ import { resolvePnpmLockfile } from "./pnpm.js";
5
+ /**
6
+ * Resolves direct dependency versions from an npm or pnpm lockfile.
7
+ */
8
+ export async function resolveLockfile(lockfilePath, packageManager) {
9
+ if (packageManager === PackageManagers.Npm) {
10
+ return resolveNpmLockfile(lockfilePath);
11
+ }
12
+ return resolvePnpmLockfile(lockfilePath);
13
+ }
14
+ /**
15
+ * Reads a UTF-8 text file from disk.
16
+ */
17
+ export async function readText(filePath) {
18
+ return readFile(filePath, "utf8");
19
+ }
20
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/lockfile/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAuB,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGhD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,YAAoB,EACpB,cAA8B;IAE9B,IAAI,cAAc,KAAK,eAAe,CAAC,GAAG,EAAE,CAAC;QAC3C,OAAO,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC7C,OAAO,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,49 @@
1
+ export interface LockPackage {
2
+ name: string;
3
+ version: string;
4
+ /** Install / lockfile scope used for path-for-path comparison. */
5
+ path: string;
6
+ /** True when the lockfile marks this install as optional. */
7
+ optional?: boolean;
8
+ }
9
+ export interface Resolution {
10
+ dependencies: LockPackage[];
11
+ devDependencies: LockPackage[];
12
+ }
13
+ export interface NpmLockfileDependency {
14
+ version?: string;
15
+ dev?: boolean;
16
+ optional?: boolean;
17
+ dependencies?: Record<string, NpmLockfileDependency>;
18
+ }
19
+ export interface NpmLockfile {
20
+ lockfileVersion?: number;
21
+ packages?: Record<string, NpmLockfileDependency>;
22
+ dependencies?: Record<string, NpmLockfileDependency>;
23
+ devDependencies?: Record<string, NpmLockfileDependency>;
24
+ }
25
+ export interface PnpmLockfilePackage {
26
+ version?: string;
27
+ dev?: boolean;
28
+ optional?: boolean;
29
+ dependencies?: Record<string, string>;
30
+ optionalDependencies?: Record<string, string>;
31
+ peerDependencies?: Record<string, string>;
32
+ devDependencies?: Record<string, string>;
33
+ }
34
+ export interface PnpmImporterDep {
35
+ specifier?: string;
36
+ version?: string;
37
+ }
38
+ export interface PnpmImporter {
39
+ dependencies?: Record<string, PnpmImporterDep | string>;
40
+ devDependencies?: Record<string, PnpmImporterDep | string>;
41
+ optionalDependencies?: Record<string, PnpmImporterDep | string>;
42
+ peerDependencies?: Record<string, PnpmImporterDep | string>;
43
+ }
44
+ export interface PnpmLockfile {
45
+ lockfileVersion?: string | number;
46
+ importers?: Record<string, PnpmImporter>;
47
+ packages?: Record<string, PnpmLockfilePackage>;
48
+ snapshots?: Record<string, PnpmLockfilePackage>;
49
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lockfile/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Resolves the absolute path to the pinned cve-lite-cli binary on disk.
3
+ * Throws BeefupError when the package or bin entry is missing.
4
+ */
5
+ export declare function resolveCveLiteBin(): Promise<string>;
@@ -0,0 +1,36 @@
1
+ import { createRequire } from "node:module";
2
+ import path from "node:path";
3
+ import { BeefupError } from "../errors.js";
4
+ import { pathExists, readJsonFile } from "../fsutil.js";
5
+ /**
6
+ * Resolves the absolute path to the pinned cve-lite-cli binary on disk.
7
+ * Throws BeefupError when the package or bin entry is missing.
8
+ */
9
+ export async function resolveCveLiteBin() {
10
+ const require = createRequire(import.meta.url);
11
+ let pkgJsonPath;
12
+ try {
13
+ pkgJsonPath = require.resolve("cve-lite-cli/package.json");
14
+ }
15
+ catch {
16
+ throw new BeefupError("cve-lite-cli is not installed; Beefup requires it as a pinned dependency");
17
+ }
18
+ const pkg = await readJsonFile(pkgJsonPath);
19
+ const binField = pkg.bin;
20
+ let rel;
21
+ if (typeof binField === "string") {
22
+ rel = binField;
23
+ }
24
+ else if (binField && typeof binField === "object") {
25
+ rel = binField["cve-lite"] ?? Object.values(binField)[0];
26
+ }
27
+ if (!rel) {
28
+ throw new BeefupError("cve-lite-cli package.json is missing a bin entry");
29
+ }
30
+ const resolved = path.resolve(path.dirname(pkgJsonPath), rel);
31
+ if (!(await pathExists(resolved))) {
32
+ throw new BeefupError(`cve-lite binary not found at ${resolved}`);
33
+ }
34
+ return resolved;
35
+ }
36
+ //# sourceMappingURL=cve-lite-bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cve-lite-bin.js","sourceRoot":"","sources":["../../src/pm/cve-lite-bin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMxD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CACnB,0EAA0E,CAC3E,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,YAAY,CAAiB,WAAW,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC;IACzB,IAAI,GAAuB,CAAC;IAC5B,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,GAAG,GAAG,QAAQ,CAAC;IACjB,CAAC;SAAM,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACpD,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,WAAW,CAAC,kDAAkD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,WAAW,CAAC,gCAAgC,QAAQ,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { type PackageManager } from "../project/types.js";
2
+ import type { ProcessRunner } from "./runner.js";
3
+ import type { ProtectedPm } from "./safe-chain.js";
4
+ /**
5
+ * Frozen-lockfile install argv per package manager (never a bare mutating install).
6
+ */
7
+ export declare const FrozenInstallArgv: {
8
+ readonly npm: readonly ["ci"];
9
+ readonly pnpm: readonly ["install", "--frozen-lockfile"];
10
+ };
11
+ /**
12
+ * Returns argv that installs node_modules exactly from the current lockfile.
13
+ */
14
+ export declare function frozenInstallArgs(packageManager: PackageManager): string[];
15
+ /**
16
+ * Installs packages from the live lockfile through a Safe Chain–protected package manager.
17
+ * Uses `npm ci` or `pnpm install --frozen-lockfile` so the reviewed lockfile is not rewritten.
18
+ */
19
+ export declare function installFromLockfile(options: {
20
+ pm: ProtectedPm;
21
+ packageManager: PackageManager;
22
+ cwd: string;
23
+ runner: ProcessRunner;
24
+ }): Promise<void>;
@@ -0,0 +1,30 @@
1
+ import { BeefupError } from "../errors.js";
2
+ import { PackageManagers } from "../project/types.js";
3
+ /**
4
+ * Frozen-lockfile install argv per package manager (never a bare mutating install).
5
+ */
6
+ export const FrozenInstallArgv = {
7
+ [PackageManagers.Npm]: ["ci"],
8
+ [PackageManagers.Pnpm]: ["install", "--frozen-lockfile"],
9
+ };
10
+ /**
11
+ * Returns argv that installs node_modules exactly from the current lockfile.
12
+ */
13
+ export function frozenInstallArgs(packageManager) {
14
+ return [...FrozenInstallArgv[packageManager]];
15
+ }
16
+ /**
17
+ * Installs packages from the live lockfile through a Safe Chain–protected package manager.
18
+ * Uses `npm ci` or `pnpm install --frozen-lockfile` so the reviewed lockfile is not rewritten.
19
+ */
20
+ export async function installFromLockfile(options) {
21
+ const args = [
22
+ ...options.pm.prefixArgs,
23
+ ...frozenInstallArgs(options.packageManager),
24
+ ];
25
+ const result = await options.runner.run(options.pm.bin, args, options.cwd);
26
+ if (result.code !== 0) {
27
+ throw new BeefupError(`frozen install failed (${options.pm.bin} ${args.join(" ")}):\n${result.stderr || result.stdout}`);
28
+ }
29
+ }
30
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/pm/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAuB,MAAM,qBAAqB,CAAC;AAI3E;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;IAC7B,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,mBAAmB,CAAC;CAChD,CAAC;AAEX;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,cAA8B;IAC9D,OAAO,CAAC,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAKzC;IACC,MAAM,IAAI,GAAG;QACX,GAAG,OAAO,CAAC,EAAE,CAAC,UAAU;QACxB,GAAG,iBAAiB,CAAC,OAAO,CAAC,cAAc,CAAC;KAC7C,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3E,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,WAAW,CACnB,0BAA0B,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAClG,CAAC;IACJ,CAAC;AACH,CAAC"}