@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,60 @@
1
+ import path from "node:path";
2
+ import { loadConfig } from "../config/load.js";
3
+ import { defaultProcessRunner } from "../pm/runner.js";
4
+ import { assertNpmVersion, resolveProtectedPm } from "../pm/safe-chain.js";
5
+ import { regenerateLockfile } from "../pm/update.js";
6
+ import { collectStagedOutputs } from "../project/collect.js";
7
+ import { detectProject } from "../project/detect.js";
8
+ import { PackageManagers } from "../project/types.js";
9
+ import { lockfilePathFor, repinWorkspace, rewriteWorkspace } from "../rewrite/workspace.js";
10
+ import { createStageStrategy } from "../strategy/index.js";
11
+ import { runReport } from "./report.js";
12
+ /**
13
+ * Stages a dependency upgrade into `.beefup/staged`, then regenerates the report.
14
+ * Uses the selected isolation strategy and restores the workspace on exit or signal.
15
+ */
16
+ export async function runStage(options) {
17
+ const projectRoot = path.resolve(options.projectRoot);
18
+ const runner = options.runner ?? defaultProcessRunner;
19
+ const project = await detectProject(projectRoot);
20
+ const config = await loadConfig(projectRoot, options.mode);
21
+ const protectedPm = await resolveProtectedPm(project.packageManager);
22
+ if (project.packageManager === PackageManagers.Npm) {
23
+ await assertNpmVersion(protectedPm);
24
+ }
25
+ const strategy = createStageStrategy(options.strategy, projectRoot, project.lockfileName);
26
+ /**
27
+ * Cleans up the staging strategy and exits when the process receives SIGINT/SIGTERM.
28
+ */
29
+ const onSignal = () => {
30
+ void strategy.cleanup().finally(() => process.exit(1));
31
+ };
32
+ process.on("SIGINT", onSignal);
33
+ process.on("SIGTERM", onSignal);
34
+ try {
35
+ const workspace = await strategy.prepare();
36
+ await rewriteWorkspace(workspace.root, config.mode);
37
+ await regenerateLockfile({
38
+ pm: protectedPm,
39
+ packageManager: project.packageManager,
40
+ cwd: workspace.root,
41
+ runner,
42
+ });
43
+ await repinWorkspace(workspace.root, lockfilePathFor(workspace.root, project.lockfileName), project.packageManager);
44
+ await collectStagedOutputs(workspace.root, projectRoot, project.lockfileName);
45
+ }
46
+ finally {
47
+ process.off("SIGINT", onSignal);
48
+ process.off("SIGTERM", onSignal);
49
+ await strategy.cleanup();
50
+ }
51
+ return runReport({
52
+ projectRoot,
53
+ mode: config.mode,
54
+ strategy: options.strategy,
55
+ format: options.format,
56
+ runner,
57
+ });
58
+ }
59
+ export { printReport } from "./report.js";
60
+ //# sourceMappingURL=stage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage.js","sourceRoot":"","sources":["../../src/commands/stage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type BeefupConfig, type UpgradeMode } from "./types.js";
2
+ /**
3
+ * Loads and merges Beefup config from package.json and pnpm-workspace.yaml.
4
+ * An optional mode override (e.g. CLI `--mode`) wins over file config.
5
+ */
6
+ export declare function loadConfig(projectRoot: string, modeOverride?: UpgradeMode): Promise<BeefupConfig>;
@@ -0,0 +1,103 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { BeefupError } from "../errors.js";
5
+ import { pathExists, readJsonFile } from "../fsutil.js";
6
+ import { DEFAULT_CONFIG, isAlignmentAction, isUpgradeMode, } from "./types.js";
7
+ /**
8
+ * Returns a string array when `value` is an array of strings; otherwise undefined.
9
+ */
10
+ function asStringArray(value) {
11
+ if (!Array.isArray(value)) {
12
+ return undefined;
13
+ }
14
+ if (value.every((item) => typeof item === "string")) {
15
+ return value;
16
+ }
17
+ return undefined;
18
+ }
19
+ /**
20
+ * Extracts known Beefup config fields from a raw object, ignoring unknown shapes.
21
+ */
22
+ function parsePartial(raw) {
23
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
24
+ return {};
25
+ }
26
+ const input = raw;
27
+ const partial = {};
28
+ if (isUpgradeMode(input.mode)) {
29
+ partial.mode = input.mode;
30
+ }
31
+ const banned = asStringArray(input.bannedRanges);
32
+ if (banned) {
33
+ partial.bannedRanges = banned;
34
+ }
35
+ if (typeof input.preferExact === "boolean") {
36
+ partial.preferExact = input.preferExact;
37
+ }
38
+ if (isAlignmentAction(input.alignment)) {
39
+ partial.alignment = input.alignment;
40
+ }
41
+ if (Array.isArray(input.alignedGroups)) {
42
+ partial.alignedGroups = input.alignedGroups.flatMap((group) => {
43
+ if (!group || typeof group !== "object" || Array.isArray(group)) {
44
+ return [];
45
+ }
46
+ const g = group;
47
+ if (typeof g.name !== "string" || typeof g.source !== "string") {
48
+ return [];
49
+ }
50
+ const packages = asStringArray(g.packages);
51
+ if (!packages) {
52
+ return [];
53
+ }
54
+ return [
55
+ {
56
+ name: g.name,
57
+ source: g.source,
58
+ packages,
59
+ onMismatch: isAlignmentAction(g.onMismatch)
60
+ ? g.onMismatch
61
+ : undefined,
62
+ },
63
+ ];
64
+ });
65
+ }
66
+ return partial;
67
+ }
68
+ /**
69
+ * Loads and merges Beefup config from package.json and pnpm-workspace.yaml.
70
+ * An optional mode override (e.g. CLI `--mode`) wins over file config.
71
+ */
72
+ export async function loadConfig(projectRoot, modeOverride) {
73
+ const pkgPath = path.join(projectRoot, "package.json");
74
+ if (!(await pathExists(pkgPath))) {
75
+ throw new BeefupError(`no package.json at ${pkgPath}`);
76
+ }
77
+ const pkg = await readJsonFile(pkgPath);
78
+ const fromPkg = parsePartial(pkg.beefup);
79
+ let fromWorkspace = {};
80
+ const workspacePath = path.join(projectRoot, "pnpm-workspace.yaml");
81
+ if (await pathExists(workspacePath)) {
82
+ const parsed = parseYaml(await readFile(workspacePath, "utf8"));
83
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
84
+ fromWorkspace = parsePartial(parsed.beefup);
85
+ }
86
+ }
87
+ const merged = {
88
+ ...DEFAULT_CONFIG,
89
+ ...fromPkg,
90
+ ...fromWorkspace,
91
+ bannedRanges: fromWorkspace.bannedRanges ??
92
+ fromPkg.bannedRanges ??
93
+ DEFAULT_CONFIG.bannedRanges,
94
+ alignedGroups: fromWorkspace.alignedGroups ??
95
+ fromPkg.alignedGroups ??
96
+ DEFAULT_CONFIG.alignedGroups,
97
+ };
98
+ if (modeOverride) {
99
+ merged.mode = modeOverride;
100
+ }
101
+ return merged;
102
+ }
103
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /** Closed set of upgrade modes Beefup can apply when rewriting constraints. */
2
+ export declare const UpgradeModes: {
3
+ readonly SameMajor: "same-major";
4
+ readonly Latest: "latest";
5
+ };
6
+ /** Upgrade mode selecting same-major or latest constraint rewriting. */
7
+ export type UpgradeMode = (typeof UpgradeModes)[keyof typeof UpgradeModes];
8
+ /** Closed set of isolation strategies used while staging an upgrade. */
9
+ export declare const StageStrategies: {
10
+ readonly Worktree: "worktree";
11
+ readonly Inplace: "inplace";
12
+ };
13
+ /** Strategy name for how the staging workspace is isolated. */
14
+ export type StageStrategyName = (typeof StageStrategies)[keyof typeof StageStrategies];
15
+ /** Closed set of report formats written to stdout. */
16
+ export declare const ReportFormats: {
17
+ readonly Color: "color";
18
+ readonly Text: "text";
19
+ readonly Markdown: "markdown";
20
+ readonly Json: "json";
21
+ readonly Html: "html";
22
+ };
23
+ /** Format used when printing a stage/report result to stdout. */
24
+ export type ReportFormat = (typeof ReportFormats)[keyof typeof ReportFormats];
25
+ /** Closed set of policy actions for alignment and similar findings. */
26
+ export declare const AlignmentActions: {
27
+ readonly Error: "error";
28
+ readonly Warn: "warn";
29
+ };
30
+ /** Whether an alignment mismatch fails the run or only warns. */
31
+ export type AlignmentAction = (typeof AlignmentActions)[keyof typeof AlignmentActions];
32
+ /** Floating tags/ranges that projects may ban in dependency specs. */
33
+ export declare const BannedRangeTags: {
34
+ readonly Latest: "latest";
35
+ readonly Any: "*";
36
+ };
37
+ /** Top-level CLI command names Beefup accepts. */
38
+ export declare const CliCommands: {
39
+ readonly Stage: "stage";
40
+ readonly Report: "report";
41
+ readonly Accept: "accept";
42
+ };
43
+ /** CLI command name (`stage`, `report`, or `accept`). */
44
+ export type CliCommand = (typeof CliCommands)[keyof typeof CliCommands];
45
+ /**
46
+ * Returns true when `value` is a known upgrade mode.
47
+ */
48
+ export declare function isUpgradeMode(value: unknown): value is UpgradeMode;
49
+ /**
50
+ * Returns true when `value` is a known stage strategy.
51
+ */
52
+ export declare function isStageStrategy(value: unknown): value is StageStrategyName;
53
+ /**
54
+ * Returns true when `value` is a known report format.
55
+ */
56
+ export declare function isReportFormat(value: unknown): value is ReportFormat;
57
+ /**
58
+ * Returns true when `value` is a known alignment action.
59
+ */
60
+ export declare function isAlignmentAction(value: unknown): value is AlignmentAction;
61
+ export interface AlignedGroup {
62
+ name: string;
63
+ source: string;
64
+ packages: string[];
65
+ onMismatch?: AlignmentAction;
66
+ }
67
+ export interface BeefupConfig {
68
+ mode: UpgradeMode;
69
+ bannedRanges: string[];
70
+ preferExact: boolean;
71
+ alignedGroups: AlignedGroup[];
72
+ alignment?: AlignmentAction;
73
+ }
74
+ /** Default Beefup project config when none is supplied in package manifests. */
75
+ export declare const DEFAULT_CONFIG: BeefupConfig;
@@ -0,0 +1,68 @@
1
+ /** Closed set of upgrade modes Beefup can apply when rewriting constraints. */
2
+ export const UpgradeModes = {
3
+ SameMajor: "same-major",
4
+ Latest: "latest",
5
+ };
6
+ /** Closed set of isolation strategies used while staging an upgrade. */
7
+ export const StageStrategies = {
8
+ Worktree: "worktree",
9
+ Inplace: "inplace",
10
+ };
11
+ /** Closed set of report formats written to stdout. */
12
+ export const ReportFormats = {
13
+ Color: "color",
14
+ Text: "text",
15
+ Markdown: "markdown",
16
+ Json: "json",
17
+ Html: "html",
18
+ };
19
+ /** Closed set of policy actions for alignment and similar findings. */
20
+ export const AlignmentActions = {
21
+ Error: "error",
22
+ Warn: "warn",
23
+ };
24
+ /** Floating tags/ranges that projects may ban in dependency specs. */
25
+ export const BannedRangeTags = {
26
+ Latest: UpgradeModes.Latest,
27
+ Any: "*",
28
+ };
29
+ /** Top-level CLI command names Beefup accepts. */
30
+ export const CliCommands = {
31
+ Stage: "stage",
32
+ Report: "report",
33
+ Accept: "accept",
34
+ };
35
+ /**
36
+ * Returns true when `value` is a known upgrade mode.
37
+ */
38
+ export function isUpgradeMode(value) {
39
+ return (value === UpgradeModes.SameMajor || value === UpgradeModes.Latest);
40
+ }
41
+ /**
42
+ * Returns true when `value` is a known stage strategy.
43
+ */
44
+ export function isStageStrategy(value) {
45
+ return (value === StageStrategies.Worktree || value === StageStrategies.Inplace);
46
+ }
47
+ /**
48
+ * Returns true when `value` is a known report format.
49
+ */
50
+ export function isReportFormat(value) {
51
+ return (typeof value === "string" &&
52
+ Object.values(ReportFormats).includes(value));
53
+ }
54
+ /**
55
+ * Returns true when `value` is a known alignment action.
56
+ */
57
+ export function isAlignmentAction(value) {
58
+ return (value === AlignmentActions.Error || value === AlignmentActions.Warn);
59
+ }
60
+ /** Default Beefup project config when none is supplied in package manifests. */
61
+ export const DEFAULT_CONFIG = {
62
+ mode: UpgradeModes.SameMajor,
63
+ bannedRanges: [BannedRangeTags.Latest, BannedRangeTags.Any],
64
+ preferExact: true,
65
+ alignedGroups: [],
66
+ alignment: AlignmentActions.Error,
67
+ };
68
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,QAAQ;CACR,CAAC;AAKX,wEAAwE;AACxE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,SAAS;CACV,CAAC;AAMX,sDAAsD;AACtD,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,UAAU;IACpB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;CACJ,CAAC;AAKX,uEAAuE;AACvE,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;CACJ,CAAC;AAMX,sEAAsE;AACtE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,MAAM,EAAE,YAAY,CAAC,MAAM;IAC3B,GAAG,EAAE,GAAG;CACA,CAAC;AAEX,kDAAkD;AAClD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;CACR,CAAC;AAKX;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,CACL,KAAK,KAAK,YAAY,CAAC,SAAS,IAAI,KAAK,KAAK,YAAY,CAAC,MAAM,CAClE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,CACL,KAAK,KAAK,eAAe,CAAC,QAAQ,IAAI,KAAK,KAAK,eAAe,CAAC,OAAO,CACxE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACxB,MAAM,CAAC,MAAM,CAAC,aAAa,CAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,CAC3D,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,CACL,KAAK,KAAK,gBAAgB,CAAC,KAAK,IAAI,KAAK,KAAK,gBAAgB,CAAC,IAAI,CACpE,CAAC;AACJ,CAAC;AAiBD,gFAAgF;AAChF,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,IAAI,EAAE,YAAY,CAAC,SAAS;IAC5B,YAAY,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,CAAC;IAC3D,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,EAAE;IACjB,SAAS,EAAE,gBAAgB,CAAC,KAAK;CAClC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { Resolution } from "../lockfile/types.js";
2
+ import { type ResolutionDiff, type ScopedVersion } from "./types.js";
3
+ /**
4
+ * Compares two lockfile resolutions and returns added, removed, and changed
5
+ * packages. Versions are compared path-for-path within each package name.
6
+ * Path-only churn (identical unique versions) is omitted.
7
+ */
8
+ export declare function diffResolutions(source: Resolution, target: Resolution): ResolutionDiff;
9
+ /**
10
+ * Annotates diff entries with direct-dependency and optional/platform flags.
11
+ */
12
+ export declare function annotatePackageChanges(diff: ResolutionDiff, options: {
13
+ directNames: ReadonlySet<string>;
14
+ optionalDeclaredNames: ReadonlySet<string>;
15
+ before: Resolution;
16
+ after: Resolution;
17
+ }): ResolutionDiff;
18
+ /**
19
+ * Unique version tags from scoped installs, sorted and comma-separated for display.
20
+ */
21
+ export declare function formatUniqueVersions(scoped: ScopedVersion[]): string;
@@ -0,0 +1,132 @@
1
+ import { PackageChangeTypes, } from "./types.js";
2
+ /**
3
+ * Compares two lockfile resolutions and returns added, removed, and changed
4
+ * packages. Versions are compared path-for-path within each package name.
5
+ * Path-only churn (identical unique versions) is omitted.
6
+ */
7
+ export function diffResolutions(source, target) {
8
+ return {
9
+ dependencies: diffPackages(source.dependencies, target.dependencies),
10
+ devDependencies: diffPackages(source.devDependencies, target.devDependencies),
11
+ };
12
+ }
13
+ /**
14
+ * Annotates diff entries with direct-dependency and optional/platform flags.
15
+ */
16
+ export function annotatePackageChanges(diff, options) {
17
+ return {
18
+ dependencies: annotateList(diff.dependencies, options, "dependencies"),
19
+ devDependencies: annotateList(diff.devDependencies, options, "devDependencies"),
20
+ };
21
+ }
22
+ /**
23
+ * Diffs two package lists by name, comparing only matching scopes/paths.
24
+ */
25
+ function diffPackages(source, target) {
26
+ const sourceByName = groupByName(source);
27
+ const targetByName = groupByName(target);
28
+ const names = new Set([...sourceByName.keys(), ...targetByName.keys()]);
29
+ const changes = [];
30
+ for (const name of [...names].sort((a, b) => a.localeCompare(b))) {
31
+ const from = sourceByName.get(name) ?? [];
32
+ const to = targetByName.get(name) ?? [];
33
+ if (from.length === 0) {
34
+ changes.push({
35
+ name,
36
+ type: PackageChangeTypes.Added,
37
+ from: [],
38
+ to,
39
+ });
40
+ continue;
41
+ }
42
+ if (to.length === 0) {
43
+ changes.push({
44
+ name,
45
+ type: PackageChangeTypes.Removed,
46
+ from,
47
+ to: [],
48
+ });
49
+ continue;
50
+ }
51
+ if (scopesDiffer(from, to) && uniqueVersionsDiffer(from, to)) {
52
+ changes.push({
53
+ name,
54
+ type: PackageChangeTypes.Changed,
55
+ from,
56
+ to,
57
+ });
58
+ }
59
+ }
60
+ return changes;
61
+ }
62
+ /**
63
+ * Applies direct/optional flags onto one package-change list.
64
+ */
65
+ function annotateList(changes, options, bucket) {
66
+ const lockPkgs = [
67
+ ...options.before[bucket],
68
+ ...options.after[bucket],
69
+ ];
70
+ return changes.map((change) => {
71
+ const optionalFromLock = lockPkgs.some((pkg) => pkg.name === change.name && pkg.optional === true);
72
+ return {
73
+ ...change,
74
+ direct: options.directNames.has(change.name),
75
+ optional: optionalFromLock || options.optionalDeclaredNames.has(change.name),
76
+ };
77
+ });
78
+ }
79
+ /**
80
+ * Groups lock packages by name into sorted scoped version lists.
81
+ */
82
+ function groupByName(packages) {
83
+ const grouped = new Map();
84
+ for (const pkg of packages) {
85
+ const list = grouped.get(pkg.name) ?? [];
86
+ list.push({ path: pkg.path, version: pkg.version });
87
+ grouped.set(pkg.name, list);
88
+ }
89
+ for (const [name, list] of grouped) {
90
+ list.sort((a, b) => a.path.localeCompare(b.path));
91
+ grouped.set(name, list);
92
+ }
93
+ return grouped;
94
+ }
95
+ /**
96
+ * Returns true when any scope path is missing on one side or has a different version.
97
+ */
98
+ function scopesDiffer(from, to) {
99
+ const fromMap = new Map(from.map((item) => [item.path, item.version]));
100
+ const toMap = new Map(to.map((item) => [item.path, item.version]));
101
+ const paths = new Set([...fromMap.keys(), ...toMap.keys()]);
102
+ for (const path of paths) {
103
+ if (fromMap.get(path) !== toMap.get(path)) {
104
+ return true;
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ /**
110
+ * Returns true when the set of unique version tags differs between from and to.
111
+ */
112
+ function uniqueVersionsDiffer(from, to) {
113
+ const fromKey = [...new Set(from.map((item) => item.version))]
114
+ .sort((a, b) => a.localeCompare(b))
115
+ .join("\0");
116
+ const toKey = [...new Set(to.map((item) => item.version))]
117
+ .sort((a, b) => a.localeCompare(b))
118
+ .join("\0");
119
+ return fromKey !== toKey;
120
+ }
121
+ /**
122
+ * Unique version tags from scoped installs, sorted and comma-separated for display.
123
+ */
124
+ export function formatUniqueVersions(scoped) {
125
+ if (scoped.length === 0) {
126
+ return "—";
127
+ }
128
+ return [...new Set(scoped.map((item) => item.version))]
129
+ .sort((a, b) => a.localeCompare(b))
130
+ .join(", ");
131
+ }
132
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/diff/diff.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,GAInB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAkB,EAClB,MAAkB;IAElB,OAAO;QACL,YAAY,EAAE,YAAY,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC;QACpE,eAAe,EAAE,YAAY,CAC3B,MAAM,CAAC,eAAe,EACtB,MAAM,CAAC,eAAe,CACvB;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAoB,EACpB,OAKC;IAED,OAAO;QACL,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,cAAc,CAAC;QACtE,eAAe,EAAE,YAAY,CAC3B,IAAI,CAAC,eAAe,EACpB,OAAO,EACP,iBAAiB,CAClB;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CACnB,MAAqB,EACrB,MAAqB;IAErB,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,EAAE,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACxE,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAExC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI;gBACJ,IAAI,EAAE,kBAAkB,CAAC,KAAK;gBAC9B,IAAI,EAAE,EAAE;gBACR,EAAE;aACH,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI;gBACJ,IAAI,EAAE,kBAAkB,CAAC,OAAO;gBAChC,IAAI;gBACJ,EAAE,EAAE,EAAE;aACP,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI;gBACJ,IAAI,EAAE,kBAAkB,CAAC,OAAO;gBAChC,IAAI;gBACJ,EAAE;aACH,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CACnB,OAAwB,EACxB,OAKC,EACD,MAA0C;IAE1C,MAAM,QAAQ,GAAG;QACf,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;QACzB,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;KACzB,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC5B,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CACpC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,CAC3D,CAAC;QACF,OAAO;YACL,GAAG,MAAM;YACT,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YAC5C,QAAQ,EACN,gBAAgB,IAAI,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;SACrE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,QAAuB;IAC1C,MAAM,OAAO,GAAG,IAAI,GAAG,EAA2B,CAAC;IACnD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,IAAqB,EAAE,EAAmB;IAC9D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,IAAqB,EAAE,EAAmB;IACtE,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SAClC,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;SACvD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SAClC,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,OAAO,KAAK,KAAK,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAuB;IAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;SACpD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SAClC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type GroupedChanges, type PackageChange } from "./types.js";
2
+ /**
3
+ * Buckets package changes into added, removed, and changed groups for reporting.
4
+ */
5
+ export declare function groupByChangeType(changes: PackageChange[]): GroupedChanges;
@@ -0,0 +1,24 @@
1
+ import { PackageChangeTypes, } from "./types.js";
2
+ /**
3
+ * Buckets package changes into added, removed, and changed groups for reporting.
4
+ */
5
+ export function groupByChangeType(changes) {
6
+ const result = {
7
+ added: [],
8
+ removed: [],
9
+ changed: [],
10
+ };
11
+ for (const change of changes) {
12
+ if (change.type === PackageChangeTypes.Added) {
13
+ result.added.push(change);
14
+ }
15
+ else if (change.type === PackageChangeTypes.Removed) {
16
+ result.removed.push(change);
17
+ }
18
+ else if (change.type === PackageChangeTypes.Changed) {
19
+ result.changed.push(change);
20
+ }
21
+ }
22
+ return result;
23
+ }
24
+ //# sourceMappingURL=group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group.js","sourceRoot":"","sources":["../../src/diff/group.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAGnB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAwB;IACxD,MAAM,MAAM,GAAmB;QAC7B,KAAK,EAAE,EAAE;QACT,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE;KACZ,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,IAAI,KAAK,kBAAkB,CAAC,KAAK,EAAE,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,MAAM,CAAC,IAAI,KAAK,kBAAkB,CAAC,OAAO,EAAE,CAAC;YACtD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;aAAM,IAAI,MAAM,CAAC,IAAI,KAAK,kBAAkB,CAAC,OAAO,EAAE,CAAC;YACtD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,37 @@
1
+ /** How a package name changed between two lockfile resolutions. */
2
+ export declare const PackageChangeTypes: {
3
+ readonly Added: "added";
4
+ readonly Removed: "removed";
5
+ readonly Changed: "changed";
6
+ };
7
+ /** Package change kind (added, removed, or changed at one or more scopes). */
8
+ export type PackageChangeType = (typeof PackageChangeTypes)[keyof typeof PackageChangeTypes];
9
+ /** One concrete install of a package at a specific lockfile scope/path. */
10
+ export interface ScopedVersion {
11
+ path: string;
12
+ version: string;
13
+ }
14
+ /**
15
+ * Diff entry for one package name across all of its scoped installs.
16
+ * `from` / `to` are scope-aware; renderers may show unique version tags only.
17
+ */
18
+ export interface PackageChange {
19
+ name: string;
20
+ type: PackageChangeType;
21
+ from: ScopedVersion[];
22
+ to: ScopedVersion[];
23
+ /** True when the package is declared in a workspace package.json. */
24
+ direct?: boolean;
25
+ /** True when the package is optional/platform in the lockfile or manifests. */
26
+ optional?: boolean;
27
+ }
28
+ export interface ResolutionDiff {
29
+ dependencies: PackageChange[];
30
+ devDependencies: PackageChange[];
31
+ }
32
+ /** Buckets package changes by added / removed / changed for reporting. */
33
+ export interface GroupedChanges {
34
+ added: PackageChange[];
35
+ removed: PackageChange[];
36
+ changed: PackageChange[];
37
+ }
@@ -0,0 +1,7 @@
1
+ /** How a package name changed between two lockfile resolutions. */
2
+ export const PackageChangeTypes = {
3
+ Added: "added",
4
+ Removed: "removed",
5
+ Changed: "changed",
6
+ };
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/diff/types.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;CACV,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Application error that carries a process exit code for the CLI.
3
+ */
4
+ export declare class BeefupError extends Error {
5
+ readonly exitCode: number;
6
+ /**
7
+ * Creates a BeefupError with a user-facing message and optional exit code.
8
+ */
9
+ constructor(message: string, exitCode?: number);
10
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Application error that carries a process exit code for the CLI.
3
+ */
4
+ export class BeefupError extends Error {
5
+ exitCode;
6
+ /**
7
+ * Creates a BeefupError with a user-facing message and optional exit code.
8
+ */
9
+ constructor(message, exitCode = 1) {
10
+ super(message);
11
+ this.name = "BeefupError";
12
+ this.exitCode = exitCode;
13
+ }
14
+ }
15
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,QAAQ,CAAS;IAE1B;;OAEG;IACH,YAAY,OAAe,EAAE,QAAQ,GAAG,CAAC;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Returns whether a filesystem path exists and is accessible.
3
+ */
4
+ export declare function pathExists(target: string): Promise<boolean>;
5
+ /**
6
+ * Reads a UTF-8 JSON file and parses it as type T.
7
+ */
8
+ export declare function readJsonFile<T>(filePath: string): Promise<T>;
9
+ /**
10
+ * Writes a value as pretty-printed JSON, creating parent directories as needed.
11
+ */
12
+ export declare function writeJsonFile(filePath: string, value: unknown): Promise<void>;
13
+ /**
14
+ * Copies a file to a destination path, creating parent directories as needed.
15
+ */
16
+ export declare function copyFileTo(src: string, dest: string): Promise<void>;
17
+ /**
18
+ * Removes a file or directory tree if it exists.
19
+ */
20
+ export declare function removePath(target: string): Promise<void>;