cliguard 0.5.0 → 0.7.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.
@@ -51,6 +51,40 @@ export interface Contract {
51
51
  readonly capturedAt: string;
52
52
  readonly root: CommandContract;
53
53
  }
54
+ /**
55
+ * A specific BREAKING change the maintainer has deliberately accepted -
56
+ * written by `cliguard accept` and committed to `.cliguard/accepted-breaks.json`
57
+ * so the decision is auditable in the repo, not a silent CLI flag. `check`
58
+ * matches these against a diff's `DiffResult.path` and stops counting a
59
+ * match toward its exit code, while still showing it in the output.
60
+ */
61
+ export interface AcceptedBreak {
62
+ /** Must equal the DiffResult.path of the breaking change being accepted, e.g. "root -> build -> option[--target]". */
63
+ readonly path: string;
64
+ /** Why this break is intentional - required, never blank, shown alongside the change. */
65
+ readonly reason: string;
66
+ /** ISO-8601 timestamp of when `cliguard accept` recorded this. */
67
+ readonly acceptedAt: string;
68
+ }
69
+ /**
70
+ * A command/option/argument the maintainer has scheduled for removal ahead
71
+ * of time - written by `cliguard deprecate` and committed to
72
+ * `.cliguard/deprecations.json`. Unlike `AcceptedBreak` (which forgives a
73
+ * break that already happened), this is recorded *before* the removal:
74
+ * `check`/`diff` reclassify a matching BREAKING removal as PATCH instead
75
+ * of failing the build, but only because the deprecation was announced in
76
+ * advance - removing something with no prior `deprecate` still fails.
77
+ */
78
+ export interface Deprecation {
79
+ /** Must equal the DiffResult.path of the eventual removal, e.g. "root -> build -> option[--target]". */
80
+ readonly path: string;
81
+ /** When this is expected to actually go away - a version ("2.0.0") or a date. Informational, never enforced by cliguard itself. */
82
+ readonly removeBy: string;
83
+ /** Why this is being deprecated - optional, shown alongside the change once it's removed. */
84
+ readonly reason?: string;
85
+ /** ISO-8601 timestamp of when `cliguard deprecate` recorded this. */
86
+ readonly deprecatedAt: string;
87
+ }
54
88
  /** Severity of a single detected difference between two contracts. */
55
89
  export declare enum ChangeType {
56
90
  /** Removes or narrows something a caller may already depend on. */
@@ -0,0 +1,31 @@
1
+ import { type CompareOptions, type DiffResult } from "./core/diff.engine";
2
+ import type { Contract } from "./core/types";
3
+ export type { CliAdapter } from "./adapters/adapter.interface";
4
+ export { CacAdapter } from "./adapters/cac.adapter";
5
+ export { CommanderAdapter } from "./adapters/commander.adapter";
6
+ export { YargsAdapter } from "./adapters/yargs.adapter";
7
+ export { adapters, resolveAdapter } from "./adapters/registry";
8
+ export { applyConfig, configExists, loadConfig } from "./core/config";
9
+ export type { CliguardConfig, SeverityOverride } from "./core/config";
10
+ export { DiffEngine } from "./core/diff.engine";
11
+ export type { CompareOptions, DiffResult } from "./core/diff.engine";
12
+ export { toGitLabCodeQuality, toJUnitXml, toRdjsonl } from "./core/report-formats";
13
+ export type { ReportChange } from "./core/report-formats";
14
+ export { ChangeType, type AcceptedBreak, type ArgumentContract, type CommandContract, type Contract, type Deprecation, type OptionContract, type OptionValueType, } from "./core/types";
15
+ /**
16
+ * Loads `entryPath` and extracts its full command surface as a Contract -
17
+ * the same extraction `cliguard init`/`check`/`update` run, without going
18
+ * through a subprocess. `adapterName` defaults to "commander", matching
19
+ * the CLI's own default.
20
+ */
21
+ export declare function extractContract(entryPath: string, adapterName?: string): Promise<Contract>;
22
+ /**
23
+ * Compares two Contracts and returns every difference, classified
24
+ * BREAKING/ADDITIVE/PATCH - the exact same comparison `cliguard check`/`diff`
25
+ * run. Framework-agnostic: neither Contract needs to have come from
26
+ * `extractContract`, so this also works against contracts read from disk
27
+ * or a git ref by the caller's own code.
28
+ */
29
+ export declare function compareContracts(oldContract: Contract, newContract: Contract, options?: CompareOptions): DiffResult[];
30
+ /** Every adapter name `extractContract`/the CLI's `--adapter` flag will accept, e.g. ["commander", "cac", "yargs"]. */
31
+ export declare function listAdapters(): string[];
package/dist/index.js ADDED
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChangeType = exports.toRdjsonl = exports.toJUnitXml = exports.toGitLabCodeQuality = exports.DiffEngine = exports.loadConfig = exports.configExists = exports.applyConfig = exports.resolveAdapter = exports.adapters = exports.YargsAdapter = exports.CommanderAdapter = exports.CacAdapter = void 0;
4
+ exports.extractContract = extractContract;
5
+ exports.compareContracts = compareContracts;
6
+ exports.listAdapters = listAdapters;
7
+ /**
8
+ * Programmatic entry point - `import { extractContract, compareContracts } from "cliguard"`.
9
+ * Everything here is the same code `bin.ts` itself calls; this file only
10
+ * adds the two convenience wrappers (`extractContract`/`compareContracts`)
11
+ * and re-exports the pieces a caller embedding cliguard in their own
12
+ * build script, monorepo tooling, or bot would need - never a second
13
+ * implementation of anything.
14
+ */
15
+ const registry_1 = require("./adapters/registry");
16
+ const diff_engine_1 = require("./core/diff.engine");
17
+ var cac_adapter_1 = require("./adapters/cac.adapter");
18
+ Object.defineProperty(exports, "CacAdapter", { enumerable: true, get: function () { return cac_adapter_1.CacAdapter; } });
19
+ var commander_adapter_1 = require("./adapters/commander.adapter");
20
+ Object.defineProperty(exports, "CommanderAdapter", { enumerable: true, get: function () { return commander_adapter_1.CommanderAdapter; } });
21
+ var yargs_adapter_1 = require("./adapters/yargs.adapter");
22
+ Object.defineProperty(exports, "YargsAdapter", { enumerable: true, get: function () { return yargs_adapter_1.YargsAdapter; } });
23
+ var registry_2 = require("./adapters/registry");
24
+ Object.defineProperty(exports, "adapters", { enumerable: true, get: function () { return registry_2.adapters; } });
25
+ Object.defineProperty(exports, "resolveAdapter", { enumerable: true, get: function () { return registry_2.resolveAdapter; } });
26
+ var config_1 = require("./core/config");
27
+ Object.defineProperty(exports, "applyConfig", { enumerable: true, get: function () { return config_1.applyConfig; } });
28
+ Object.defineProperty(exports, "configExists", { enumerable: true, get: function () { return config_1.configExists; } });
29
+ Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_1.loadConfig; } });
30
+ var diff_engine_2 = require("./core/diff.engine");
31
+ Object.defineProperty(exports, "DiffEngine", { enumerable: true, get: function () { return diff_engine_2.DiffEngine; } });
32
+ var report_formats_1 = require("./core/report-formats");
33
+ Object.defineProperty(exports, "toGitLabCodeQuality", { enumerable: true, get: function () { return report_formats_1.toGitLabCodeQuality; } });
34
+ Object.defineProperty(exports, "toJUnitXml", { enumerable: true, get: function () { return report_formats_1.toJUnitXml; } });
35
+ Object.defineProperty(exports, "toRdjsonl", { enumerable: true, get: function () { return report_formats_1.toRdjsonl; } });
36
+ var types_1 = require("./core/types");
37
+ Object.defineProperty(exports, "ChangeType", { enumerable: true, get: function () { return types_1.ChangeType; } });
38
+ const diffEngine = new diff_engine_1.DiffEngine();
39
+ /**
40
+ * Loads `entryPath` and extracts its full command surface as a Contract -
41
+ * the same extraction `cliguard init`/`check`/`update` run, without going
42
+ * through a subprocess. `adapterName` defaults to "commander", matching
43
+ * the CLI's own default.
44
+ */
45
+ async function extractContract(entryPath, adapterName = "commander") {
46
+ // Deliberately `async` rather than returning resolveAdapter(...).extract(...)
47
+ // directly - resolveAdapter throws synchronously on an unknown name, and
48
+ // without `async` that throw would escape as a synchronous exception
49
+ // instead of a rejected Promise, breaking the "this always returns a
50
+ // Promise" contract the function's own return type promises.
51
+ return (0, registry_1.resolveAdapter)(adapterName).extract(entryPath);
52
+ }
53
+ /**
54
+ * Compares two Contracts and returns every difference, classified
55
+ * BREAKING/ADDITIVE/PATCH - the exact same comparison `cliguard check`/`diff`
56
+ * run. Framework-agnostic: neither Contract needs to have come from
57
+ * `extractContract`, so this also works against contracts read from disk
58
+ * or a git ref by the caller's own code.
59
+ */
60
+ function compareContracts(oldContract, newContract, options) {
61
+ return diffEngine.compare(oldContract, newContract, options);
62
+ }
63
+ /** Every adapter name `extractContract`/the CLI's `--adapter` flag will accept, e.g. ["commander", "cac", "yargs"]. */
64
+ function listAdapters() {
65
+ return Object.keys(registry_1.adapters);
66
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cliguard",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Snapshot-tests your CLI's contract (commands, flags, defaults) so you never ship a breaking change by accident.",
5
5
  "keywords": [
6
6
  "cli",
@@ -24,6 +24,15 @@
24
24
  "bin": {
25
25
  "cliguard": "dist/bin.js"
26
26
  },
27
+ "main": "dist/index.js",
28
+ "types": "dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "default": "./dist/index.js"
33
+ },
34
+ "./package.json": "./package.json"
35
+ },
27
36
  "files": [
28
37
  "dist"
29
38
  ],