@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
@@ -0,0 +1,17 @@
1
+ /** Captured stdout, stderr, and exit code from a child process. */
2
+ export interface RunResult {
3
+ stdout: string;
4
+ stderr: string;
5
+ code: number;
6
+ }
7
+ /** Abstraction for running package-manager or scanner binaries. */
8
+ export interface ProcessRunner {
9
+ /**
10
+ * Spawns a binary with args in cwd and returns captured output and exit code.
11
+ */
12
+ run(bin: string, args: string[], cwd: string): Promise<RunResult>;
13
+ }
14
+ /**
15
+ * Default ProcessRunner that spawns a child process and collects stdout/stderr.
16
+ */
17
+ export declare const defaultProcessRunner: ProcessRunner;
@@ -0,0 +1,27 @@
1
+ import { spawn } from "node:child_process";
2
+ /**
3
+ * Default ProcessRunner that spawns a child process and collects stdout/stderr.
4
+ */
5
+ export const defaultProcessRunner = {
6
+ /**
7
+ * Spawns a binary with args in cwd and returns captured output and exit code.
8
+ */
9
+ async run(bin, args, cwd) {
10
+ return new Promise((resolve, reject) => {
11
+ const child = spawn(bin, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
12
+ const stdoutChunks = [];
13
+ const stderrChunks = [];
14
+ child.stdout.on("data", (chunk) => stdoutChunks.push(chunk));
15
+ child.stderr.on("data", (chunk) => stderrChunks.push(chunk));
16
+ child.on("error", reject);
17
+ child.on("close", (code) => {
18
+ resolve({
19
+ stdout: Buffer.concat(stdoutChunks).toString("utf8"),
20
+ stderr: Buffer.concat(stderrChunks).toString("utf8"),
21
+ code: code ?? 1,
22
+ });
23
+ });
24
+ });
25
+ },
26
+ };
27
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/pm/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAiB3C;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAkB;IACjD;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG;QACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAC3E,MAAM,YAAY,GAAa,EAAE,CAAC;YAClC,MAAM,YAAY,GAAa,EAAE,CAAC;YAClC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACrE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACrE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzB,OAAO,CAAC;oBACN,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;oBACpD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;oBACpD,IAAI,EAAE,IAAI,IAAI,CAAC;iBAChB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type PackageManager } from "../project/types.js";
2
+ export interface ProtectedPm {
3
+ bin: string;
4
+ prefixArgs: string[];
5
+ }
6
+ /**
7
+ * Returns the Aikido Safe Chain wrapper binary name for a package manager.
8
+ */
9
+ export declare function aikidoBinName(packageManager: PackageManager): string;
10
+ /**
11
+ * Locates a Safe Chain–protected package manager binary and prefix args.
12
+ */
13
+ export declare function resolveProtectedPm(packageManager: PackageManager): Promise<ProtectedPm>;
14
+ /**
15
+ * Asserts that the resolved npm binary reports major version 12 or higher.
16
+ */
17
+ export declare function assertNpmVersion(pm: ProtectedPm): Promise<void>;
@@ -0,0 +1,65 @@
1
+ import { execFile as execFileCallback } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { BeefupError } from "../errors.js";
4
+ import { PackageManagers } from "../project/types.js";
5
+ const execFile = promisify(execFileCallback);
6
+ /**
7
+ * Returns the Aikido Safe Chain wrapper binary name for a package manager.
8
+ */
9
+ export function aikidoBinName(packageManager) {
10
+ return packageManager === PackageManagers.Npm ? "aikido-npm" : "aikido-pnpm";
11
+ }
12
+ /**
13
+ * Resolves an executable on PATH via `which`, or undefined when missing.
14
+ */
15
+ async function which(bin) {
16
+ try {
17
+ const { stdout } = await execFile("which", [bin], { encoding: "utf8" });
18
+ const resolved = stdout.trim();
19
+ return resolved.length > 0 ? resolved : undefined;
20
+ }
21
+ catch {
22
+ return undefined;
23
+ }
24
+ }
25
+ /**
26
+ * Locates a Safe Chain–protected package manager binary and prefix args.
27
+ */
28
+ export async function resolveProtectedPm(packageManager) {
29
+ const aikido = await which(aikidoBinName(packageManager));
30
+ if (aikido) {
31
+ return { bin: aikido, prefixArgs: [] };
32
+ }
33
+ const safeChain = await which("safe-chain");
34
+ if (safeChain) {
35
+ return { bin: safeChain, prefixArgs: [packageManager] };
36
+ }
37
+ throw new BeefupError(`Safe-chain is not enabled: neither ${aikidoBinName(packageManager)} nor safe-chain was found on PATH. Install Aikido Safe Chain and ensure it wraps ${packageManager}.`);
38
+ }
39
+ /**
40
+ * Parses the major version number from a package manager `--version` output.
41
+ */
42
+ function parseMajorVersion(raw) {
43
+ const match = raw.trim().match(/(\d+)\./);
44
+ if (!match) {
45
+ return undefined;
46
+ }
47
+ return Number.parseInt(match[1], 10);
48
+ }
49
+ /**
50
+ * Asserts that the resolved npm binary reports major version 12 or higher.
51
+ */
52
+ export async function assertNpmVersion(pm) {
53
+ const { stdout, stderr } = await execFile(pm.bin, [...pm.prefixArgs, "--version"], {
54
+ encoding: "utf8",
55
+ });
56
+ const raw = `${stdout}\n${stderr}`;
57
+ const major = parseMajorVersion(raw);
58
+ if (major === undefined) {
59
+ throw new BeefupError(`could not parse npm version from: ${raw.trim()}`);
60
+ }
61
+ if (major < 12) {
62
+ throw new BeefupError(`npm 12+ is required (got ${raw.trim().split("\n").pop()})`);
63
+ }
64
+ }
65
+ //# sourceMappingURL=safe-chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-chain.js","sourceRoot":"","sources":["../../src/pm/safe-chain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
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
+ * Returns lockfile-only update CLI args for the given package manager.
6
+ */
7
+ export declare function lockfileUpdateArgs(packageManager: PackageManager): string[];
8
+ /**
9
+ * Regenerates the project lockfile through a Safe Chain–protected package manager.
10
+ */
11
+ export declare function regenerateLockfile(options: {
12
+ pm: ProtectedPm;
13
+ packageManager: PackageManager;
14
+ cwd: string;
15
+ runner: ProcessRunner;
16
+ }): Promise<void>;
@@ -0,0 +1,25 @@
1
+ import { BeefupError } from "../errors.js";
2
+ import { PackageManagers } from "../project/types.js";
3
+ /**
4
+ * Returns lockfile-only update CLI args for the given package manager.
5
+ */
6
+ export function lockfileUpdateArgs(packageManager) {
7
+ if (packageManager === PackageManagers.Npm) {
8
+ return ["update", "--package-lock-only", "--ignore-scripts"];
9
+ }
10
+ return ["update", "--lockfile-only", "--ignore-scripts", "--no-save"];
11
+ }
12
+ /**
13
+ * Regenerates the project lockfile through a Safe Chain–protected package manager.
14
+ */
15
+ export async function regenerateLockfile(options) {
16
+ const args = [
17
+ ...options.pm.prefixArgs,
18
+ ...lockfileUpdateArgs(options.packageManager),
19
+ ];
20
+ const result = await options.runner.run(options.pm.bin, args, options.cwd);
21
+ if (result.code !== 0) {
22
+ throw new BeefupError(`lockfile regeneration failed (${options.pm.bin} ${args.join(" ")}):\n${result.stderr || result.stdout}`);
23
+ }
24
+ }
25
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/pm/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAuB,MAAM,qBAAqB,CAAC;AAI3E;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,cAA8B;IAC/D,IAAI,cAAc,KAAK,eAAe,CAAC,GAAG,EAAE,CAAC;QAC3C,OAAO,CAAC,QAAQ,EAAE,qBAAqB,EAAE,kBAAkB,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,CAAC,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAKxC;IACC,MAAM,IAAI,GAAG;QACX,GAAG,OAAO,CAAC,EAAE,CAAC,UAAU;QACxB,GAAG,kBAAkB,CAAC,OAAO,CAAC,cAAc,CAAC;KAC9C,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,iCAAiC,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CACzG,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type AlignmentAction, type BeefupConfig } from "../config/types.js";
2
+ import type { NpmLockfile, PnpmLockfile } from "../lockfile/types.js";
3
+ import { type PackageJson } from "../project/package-json.js";
4
+ import { type PackageManager } from "../project/types.js";
5
+ export interface AlignmentFinding {
6
+ group: string;
7
+ message: string;
8
+ severity: AlignmentAction;
9
+ }
10
+ /**
11
+ * Finds alignment mismatches for every configured group in the project.
12
+ */
13
+ export declare function findAlignmentIssues(config: BeefupConfig, pkg: PackageJson, packageManager: PackageManager, lock: NpmLockfile | PnpmLockfile, workspaceOverrides?: Record<string, unknown>): AlignmentFinding[];
@@ -0,0 +1,171 @@
1
+ import { AlignmentActions, } from "../config/types.js";
2
+ import { extractPackageInfoFromName } from "../lockfile/pnpm.js";
3
+ import { DIRECT_DEP_FIELDS, } from "../project/package-json.js";
4
+ import { PackageManagers } from "../project/types.js";
5
+ /**
6
+ * Reads a pinned override value, including nested `"."` map forms.
7
+ */
8
+ function overridePin(value) {
9
+ if (typeof value === "string") {
10
+ return value;
11
+ }
12
+ if (value && typeof value === "object" && typeof value["."] === "string") {
13
+ return value["."];
14
+ }
15
+ return null;
16
+ }
17
+ /**
18
+ * Returns the direct-dependency version spec for `source` from package.json.
19
+ */
20
+ function expectedVersion(pkg, source) {
21
+ for (const field of DIRECT_DEP_FIELDS) {
22
+ const spec = pkg[field]?.[source];
23
+ if (spec) {
24
+ return spec;
25
+ }
26
+ }
27
+ return undefined;
28
+ }
29
+ /**
30
+ * Collects resolved lockfile versions for the given package names.
31
+ */
32
+ function collectLockVersions(packageManager, lock, names) {
33
+ const found = new Map();
34
+ /** Records a resolved version for a package name when it is in scope. */
35
+ const add = (name, version) => {
36
+ if (!names.has(name)) {
37
+ return;
38
+ }
39
+ const set = found.get(name) ?? new Set();
40
+ set.add(version);
41
+ found.set(name, set);
42
+ };
43
+ if (packageManager === PackageManagers.Npm) {
44
+ const packages = lock.packages ?? {};
45
+ for (const [key, meta] of Object.entries(packages)) {
46
+ if (!meta?.version) {
47
+ continue;
48
+ }
49
+ const parts = key.split("node_modules/");
50
+ const name = parts[parts.length - 1];
51
+ if (name) {
52
+ add(name, meta.version);
53
+ }
54
+ }
55
+ return found;
56
+ }
57
+ const pnpm = lock;
58
+ for (const [key, meta] of Object.entries(pnpm.packages ?? {})) {
59
+ const info = extractPackageInfoFromName(key);
60
+ if (!info) {
61
+ continue;
62
+ }
63
+ const version = meta?.version ?? info.version;
64
+ if (version) {
65
+ add(info.name, version);
66
+ }
67
+ }
68
+ for (const key of Object.keys(pnpm.snapshots ?? {})) {
69
+ const info = extractPackageInfoFromName(key);
70
+ if (info?.version) {
71
+ add(info.name, info.version);
72
+ }
73
+ }
74
+ return found;
75
+ }
76
+ /**
77
+ * Checks one aligned group for package.json, override, and lockfile mismatches.
78
+ */
79
+ function checkGroup(group, pkg, packageManager, lock, workspaceOverrides, defaultAction) {
80
+ const severity = group.onMismatch ?? defaultAction;
81
+ const expected = expectedVersion(pkg, group.source);
82
+ const findings = [];
83
+ if (!expected) {
84
+ findings.push({
85
+ group: group.name,
86
+ severity,
87
+ message: `source package ${group.source} is not a direct dependency`,
88
+ });
89
+ return findings;
90
+ }
91
+ if (/[^\d.]/.test(expected)) {
92
+ findings.push({
93
+ group: group.name,
94
+ severity,
95
+ message: `${group.source} must be an exact version, got "${expected}"`,
96
+ });
97
+ return findings;
98
+ }
99
+ const names = new Set([group.source, ...group.packages]);
100
+ for (const field of DIRECT_DEP_FIELDS) {
101
+ const bucket = pkg[field];
102
+ if (!bucket) {
103
+ continue;
104
+ }
105
+ for (const name of names) {
106
+ const actual = bucket[name];
107
+ if (actual && actual !== expected) {
108
+ findings.push({
109
+ group: group.name,
110
+ severity,
111
+ message: `${field}["${name}"] is ${actual}, expected ${expected}`,
112
+ });
113
+ }
114
+ }
115
+ }
116
+ const overrideMaps = [];
117
+ if (pkg.overrides && typeof pkg.overrides === "object") {
118
+ overrideMaps.push({ label: "package.json#overrides", map: pkg.overrides });
119
+ }
120
+ if (workspaceOverrides) {
121
+ overrideMaps.push({
122
+ label: "pnpm-workspace.yaml#overrides",
123
+ map: workspaceOverrides,
124
+ });
125
+ }
126
+ for (const { label, map } of overrideMaps) {
127
+ for (const name of group.packages) {
128
+ if (name === group.source) {
129
+ continue;
130
+ }
131
+ if (map[name] === undefined) {
132
+ continue;
133
+ }
134
+ const pinned = overridePin(map[name]);
135
+ if (pinned !== expected) {
136
+ findings.push({
137
+ group: group.name,
138
+ severity,
139
+ message: `${label}["${name}"] is ${JSON.stringify(pinned)}, expected "${expected}"`,
140
+ });
141
+ }
142
+ }
143
+ }
144
+ const found = collectLockVersions(packageManager, lock, names);
145
+ for (const name of names) {
146
+ const versions = found.get(name);
147
+ if (!versions) {
148
+ continue;
149
+ }
150
+ const unexpected = [...versions].filter((version) => version !== expected);
151
+ if (unexpected.length) {
152
+ findings.push({
153
+ group: group.name,
154
+ severity,
155
+ message: `${name}: lockfile has ${[...versions].sort().join(", ")}, expected ${expected}`,
156
+ });
157
+ }
158
+ }
159
+ return findings;
160
+ }
161
+ /**
162
+ * Finds alignment mismatches for every configured group in the project.
163
+ */
164
+ export function findAlignmentIssues(config, pkg, packageManager, lock, workspaceOverrides) {
165
+ const findings = [];
166
+ for (const group of config.alignedGroups) {
167
+ findings.push(...checkGroup(group, pkg, packageManager, lock, workspaceOverrides, config.alignment ?? AlignmentActions.Error));
168
+ }
169
+ return findings;
170
+ }
171
+ //# sourceMappingURL=alignment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alignment.js","sourceRoot":"","sources":["../../src/policy/alignment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type BeefupConfig } from "../config/types.js";
2
+ import { type PackageManager } from "../project/types.js";
3
+ import { type AlignmentFinding } from "./alignment.js";
4
+ import { type OverrideFinding } from "./overrides.js";
5
+ import { type RangeFinding } from "./ranges.js";
6
+ export interface PolicyResult {
7
+ ranges: RangeFinding[];
8
+ overrides: OverrideFinding[];
9
+ alignment: AlignmentFinding[];
10
+ warnings: string[];
11
+ }
12
+ /**
13
+ * Evaluates range, override, and alignment policy against a project workspace.
14
+ */
15
+ export declare function evaluatePolicy(root: string, packageManager: PackageManager, lockfileName: string, config: BeefupConfig): Promise<PolicyResult>;
16
+ /**
17
+ * Throws when the policy result contains any error-severity findings.
18
+ */
19
+ export declare function assertPolicy(result: PolicyResult): void;
@@ -0,0 +1,75 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { AlignmentActions } from "../config/types.js";
5
+ import { BeefupError } from "../errors.js";
6
+ import { pathExists, readJsonFile } from "../fsutil.js";
7
+ import { parseNpmLockfile } from "../lockfile/npm.js";
8
+ import { parsePnpmLockfile } from "../lockfile/pnpm.js";
9
+ import { PackageManagers } from "../project/types.js";
10
+ import { listWorkspacePackages } from "../project/workspace.js";
11
+ import { findAlignmentIssues } from "./alignment.js";
12
+ import { findStaleOverridePins, findWorkspaceOverrideDrift, normalizeLockForOverrides, } from "./overrides.js";
13
+ import { findRangeIssues } from "./ranges.js";
14
+ /**
15
+ * Evaluates range, override, and alignment policy against a project workspace.
16
+ */
17
+ export async function evaluatePolicy(root, packageManager, lockfileName, config) {
18
+ const pkg = await readJsonFile(path.join(root, "package.json"));
19
+ const lockPath = path.join(root, lockfileName);
20
+ const lockContent = await readFile(lockPath, "utf8");
21
+ const lock = packageManager === PackageManagers.Npm
22
+ ? parseNpmLockfile(lockContent)
23
+ : parsePnpmLockfile(lockContent);
24
+ let workspaceOverrides;
25
+ const workspacePath = path.join(root, "pnpm-workspace.yaml");
26
+ if (await pathExists(workspacePath)) {
27
+ const parsed = parseYaml(await readFile(workspacePath, "utf8"));
28
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
29
+ const overrides = parsed.overrides;
30
+ if (overrides && typeof overrides === "object" && !Array.isArray(overrides)) {
31
+ workspaceOverrides = overrides;
32
+ }
33
+ }
34
+ }
35
+ const ranges = [];
36
+ const workspaces = await listWorkspacePackages(root);
37
+ for (const ws of workspaces) {
38
+ const wsPkg = await readJsonFile(ws.packageJsonPath);
39
+ const label = ws.relativeDir === "." ? "package.json" : `${ws.relativeDir}/package.json`;
40
+ ranges.push(...findRangeIssues(wsPkg, config, label));
41
+ }
42
+ const normalized = normalizeLockForOverrides(packageManager, lock);
43
+ const overrides = [
44
+ ...findStaleOverridePins(pkg, normalized),
45
+ ...findWorkspaceOverrideDrift(pkg, workspaceOverrides),
46
+ ];
47
+ const alignment = findAlignmentIssues(config, pkg, packageManager, lock, workspaceOverrides);
48
+ const warnings = [
49
+ ...ranges
50
+ .filter((item) => item.severity === AlignmentActions.Warn)
51
+ .map((item) => item.message),
52
+ ...alignment
53
+ .filter((item) => item.severity === AlignmentActions.Warn)
54
+ .map((item) => `[${item.group}] ${item.message}`),
55
+ ];
56
+ return { ranges, overrides, alignment, warnings };
57
+ }
58
+ /**
59
+ * Throws when the policy result contains any error-severity findings.
60
+ */
61
+ export function assertPolicy(result) {
62
+ const errors = [
63
+ ...result.ranges
64
+ .filter((item) => item.severity === AlignmentActions.Error)
65
+ .map((item) => item.message),
66
+ ...result.overrides.map((item) => `[${item.override}] ${item.message}`),
67
+ ...result.alignment
68
+ .filter((item) => item.severity === AlignmentActions.Error)
69
+ .map((item) => `[${item.group}] ${item.message}`),
70
+ ];
71
+ if (errors.length > 0) {
72
+ throw new BeefupError(`policy failed:\n${errors.map((line) => ` - ${line}`).join("\n")}`);
73
+ }
74
+ }
75
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/policy/evaluate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { NpmLockfile, PnpmLockfile } from "../lockfile/types.js";
2
+ import type { PackageJson } from "../project/package-json.js";
3
+ import { type PackageManager } from "../project/types.js";
4
+ export interface OverrideFinding {
5
+ override: string;
6
+ message: string;
7
+ }
8
+ /**
9
+ * Parses an override key into a package name and optional version selector.
10
+ */
11
+ declare function parseOverrideKey(key: string): {
12
+ name: string;
13
+ selector: string | null;
14
+ };
15
+ interface FlatPin {
16
+ logicalName: string;
17
+ selector: string | null;
18
+ targetRaw: string;
19
+ trail: string[];
20
+ scopedTo: string | null;
21
+ }
22
+ /**
23
+ * Flattens nested npm/pnpm override maps into individual pin records.
24
+ */
25
+ declare function flattenOverrides(node: Record<string, unknown>, trail?: string[], scopedTo?: string | null): FlatPin[];
26
+ /**
27
+ * Finds override pins that are banned floating tags or below requested ranges.
28
+ */
29
+ export declare function findStaleOverridePins(pkg: PackageJson, lock: NpmLockfile | {
30
+ packages?: Record<string, unknown>;
31
+ }): OverrideFinding[];
32
+ /**
33
+ * Finds keys where package.json and pnpm-workspace.yaml overrides disagree.
34
+ */
35
+ export declare function findWorkspaceOverrideDrift(pkg: PackageJson, workspaceOverrides: Record<string, unknown> | undefined): OverrideFinding[];
36
+ /**
37
+ * Normalizes a lockfile into the packages shape used by override pin checks.
38
+ */
39
+ export declare function normalizeLockForOverrides(packageManager: PackageManager, lock: NpmLockfile | PnpmLockfile): {
40
+ packages?: Record<string, unknown>;
41
+ };
42
+ export { parseOverrideKey, flattenOverrides };