breakage 0.9.0 → 0.9.1

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.
@@ -1,91 +1,6 @@
1
1
  import { a as ReleasePolicyFunction, c as VersionTransition, d as versionDelta, f as versionTransition, i as ReleasePolicy, l as resolveReleaseDelta, n as ReleaseDeltaContext, o as SemverPolicyOptions, r as ReleaseDeltaResolver, s as VersionDelta, t as ReleaseConfig, u as semverPolicy } from "./release-D47BqRuB.js";
2
2
  import "simple-git";
3
3
  import { ConfigInput } from "comline";
4
- /** The complete config, with no fields exposed to argv by this loader. */
5
- declare const configOptions: {
6
- description: string;
7
- optionsSchema: import("arktype/internal/variants/object.ts").ObjectType<{
8
- tagPattern?: string | undefined;
9
- baselineFile?: string | undefined;
10
- testPattern?: string;
11
- testCommand?: string;
12
- test?: string;
13
- baseDirname?: string;
14
- verbose?: boolean | undefined;
15
- out?: string;
16
- release?: {
17
- resolveDelta?: ReleaseDeltaResolver;
18
- policy?: ReleasePolicyFunction;
19
- };
20
- npm?: {
21
- release?: {
22
- resolveDelta?: ReleaseDeltaResolver;
23
- policy?: ReleasePolicyFunction;
24
- };
25
- packageDirectory?: string;
26
- artifact: string;
27
- representatives: string | string[];
28
- lockfile: string;
29
- prepareCommand: string;
30
- installCommand?: string;
31
- suites: {
32
- [x: string]: {
33
- files: string[];
34
- command: string;
35
- };
36
- };
37
- localPeers?: {
38
- [x: string]: {
39
- directory: string;
40
- artifact: string;
41
- };
42
- };
43
- baseline: {
44
- firstRelease: true;
45
- } | {
46
- tagPattern?: string;
47
- baselineFile?: string;
48
- };
49
- };
50
- }, {}>;
51
- optionConfigs: {
52
- tagPattern: import("comline").ConfigOnlyOption;
53
- baselineFile: import("comline").ConfigOnlyOption;
54
- testPattern: import("comline").ConfigOnlyOption;
55
- testCommand: import("comline").ConfigOnlyOption;
56
- test: import("comline").ConfigOnlyOption;
57
- baseDirname: import("comline").ConfigOnlyOption;
58
- verbose: import("comline").ConfigOnlyOption;
59
- out: import("comline").ConfigOnlyOption;
60
- release: import("comline").ConfigOnlyOption;
61
- npm: import("comline").ConfigOnlyOption;
62
- };
63
- };
64
- type BreakageConfig = ConfigInput<typeof configOptions>;
65
- /** Share the root release model with npm checks unless they supply their own. */
66
- export declare function defineConfig(config: BreakageConfig): BreakageConfig;
67
- /** Use Comline's module loading and full-schema validation for programmatic and npm consumers. */
68
- export declare function loadConfig(filename: string): Promise<BreakageConfig>;
69
- type CommandResult = {
70
- code: number;
71
- output: string;
72
- };
73
- type BaselineOptions = {
74
- tagPattern?: string | undefined;
75
- baseDirname?: string;
76
- };
77
- type BreakagePreludeOptions = BaselineOptions & {
78
- out: string;
79
- };
80
- type BreakageBaseline = {
81
- version: 1;
82
- tagPattern: string | null;
83
- packageDirectory: string;
84
- ref: string;
85
- commit: string;
86
- };
87
- /** Resolve and fetch a release without running tests or changing the worktree. */
88
- export declare function breakagePrelude({ out, tagPattern, baseDirname }: BreakagePreludeOptions): Promise<BreakageBaseline>;
89
4
  declare const npmSuiteSchema: import("arktype/internal/variants/object.ts").ObjectType<{
90
5
  files: string[];
91
6
  command: string;
@@ -175,6 +90,185 @@ type NpmReport = {
175
90
  };
176
91
  errors: string[];
177
92
  };
93
+ type NpmArchiveRequest = {
94
+ packageName: string;
95
+ directory: string;
96
+ artifact: string;
97
+ };
98
+ type NpmPrepareContext = {
99
+ rootDirectory: string;
100
+ archives: NpmArchiveRequest[];
101
+ };
102
+ type NpmMatrixLabelContext = {
103
+ packageName: string;
104
+ representative: string;
105
+ description?: string;
106
+ peers: Record<string, NpmPeerEvidence>;
107
+ };
108
+ declare const npmMatrixConfigSchema: import("arktype/internal/variants/object.ts").ObjectType<{
109
+ configs: string | string[];
110
+ prepare: string | ((context: NpmPrepareContext) => void | Promise<void>);
111
+ label?: (context: NpmMatrixLabelContext) => string;
112
+ }, {}>;
113
+ type NpmMatrixConfig = typeof npmMatrixConfigSchema.infer;
114
+ declare const npmPlanSchema: import("arktype/internal/variants/object.ts").ObjectType<{
115
+ formatVersion: 1;
116
+ id: string;
117
+ runId: string;
118
+ commit: string;
119
+ configs: string[];
120
+ packages: {
121
+ config: string;
122
+ directory: string;
123
+ name: string;
124
+ configDigest: string;
125
+ inputDigest: string;
126
+ audit: NpmReport;
127
+ releases: {
128
+ context: {
129
+ packageName: string;
130
+ packageDirectory: string;
131
+ currentVersion: string;
132
+ baseline?: {
133
+ version: string;
134
+ ref?: string;
135
+ commit?: string;
136
+ };
137
+ };
138
+ transition?: {
139
+ previousVersion: string;
140
+ version: string;
141
+ delta: "major" | "minor" | "none" | "patch" | "premajor" | "preminor" | "prepatch" | "prerelease" | "release";
142
+ };
143
+ }[];
144
+ }[];
145
+ environments: {
146
+ id: string;
147
+ label: string;
148
+ packageName: string;
149
+ representative: string;
150
+ suites: string[];
151
+ peers: {
152
+ [x: string]: {
153
+ version: string;
154
+ source: "candidate" | "installed";
155
+ };
156
+ };
157
+ }[];
158
+ archives: {
159
+ path: string;
160
+ file: string;
161
+ sha256: string;
162
+ }[];
163
+ }, {}>;
164
+ type NpmPlan = typeof npmPlanSchema.infer;
165
+ declare const npmReceiptSchema: import("arktype/internal/variants/object.ts").ObjectType<{
166
+ formatVersion: 1;
167
+ planId: string;
168
+ id: string;
169
+ exitCode: 0 | 1 | 2;
170
+ report?: NpmReport;
171
+ error?: string;
172
+ }, {}>;
173
+ type NpmReceipt = typeof npmReceiptSchema.infer;
174
+ type NpmVerification = {
175
+ exitCode: 0 | 1 | 2;
176
+ errors: string[];
177
+ environments: number;
178
+ };
179
+ /** Pure receipt verification; runner-local installation paths are diagnostic only. */
180
+ export declare function verifyNpmReceipts(value: unknown, receipts: readonly unknown[]): NpmVerification;
181
+ /** The complete config, with no fields exposed to argv by this loader. */
182
+ declare const configOptions: {
183
+ description: string;
184
+ optionsSchema: import("arktype/internal/variants/object.ts").ObjectType<{
185
+ tagPattern?: string | undefined;
186
+ baselineFile?: string | undefined;
187
+ testPattern?: string;
188
+ testCommand?: string;
189
+ test?: string;
190
+ baseDirname?: string;
191
+ verbose?: boolean | undefined;
192
+ out?: string;
193
+ release?: {
194
+ resolveDelta?: ReleaseDeltaResolver;
195
+ policy?: ReleasePolicyFunction;
196
+ };
197
+ npm?: {
198
+ release?: {
199
+ resolveDelta?: ReleaseDeltaResolver;
200
+ policy?: ReleasePolicyFunction;
201
+ };
202
+ packageDirectory?: string;
203
+ artifact: string;
204
+ representatives: string | string[];
205
+ lockfile: string;
206
+ prepareCommand: string;
207
+ installCommand?: string;
208
+ suites: {
209
+ [x: string]: {
210
+ files: string[];
211
+ command: string;
212
+ };
213
+ };
214
+ localPeers?: {
215
+ [x: string]: {
216
+ directory: string;
217
+ artifact: string;
218
+ };
219
+ };
220
+ baseline: {
221
+ firstRelease: true;
222
+ } | {
223
+ tagPattern?: string;
224
+ baselineFile?: string;
225
+ };
226
+ };
227
+ npmMatrix?: {
228
+ configs: string | string[];
229
+ prepare: string | ((context: NpmPrepareContext) => void | Promise<void>);
230
+ label?: (context: NpmMatrixLabelContext) => string;
231
+ };
232
+ }, {}>;
233
+ optionConfigs: {
234
+ tagPattern: import("comline").ConfigOnlyOption;
235
+ baselineFile: import("comline").ConfigOnlyOption;
236
+ testPattern: import("comline").ConfigOnlyOption;
237
+ testCommand: import("comline").ConfigOnlyOption;
238
+ test: import("comline").ConfigOnlyOption;
239
+ baseDirname: import("comline").ConfigOnlyOption;
240
+ verbose: import("comline").ConfigOnlyOption;
241
+ out: import("comline").ConfigOnlyOption;
242
+ release: import("comline").ConfigOnlyOption;
243
+ npm: import("comline").ConfigOnlyOption;
244
+ npmMatrix: import("comline").ConfigOnlyOption;
245
+ };
246
+ };
247
+ type BreakageConfig = ConfigInput<typeof configOptions>;
248
+ /** Share the root release model with npm checks unless they supply their own. */
249
+ export declare function defineConfig(config: BreakageConfig): BreakageConfig;
250
+ /** Use Comline's module loading and full-schema validation for programmatic and npm consumers. */
251
+ export declare function loadConfig(filename: string): Promise<BreakageConfig>;
252
+ type CommandResult = {
253
+ code: number;
254
+ output: string;
255
+ };
256
+ type BaselineOptions = {
257
+ tagPattern?: string | undefined;
258
+ baseDirname?: string;
259
+ };
260
+ type BreakagePreludeOptions = BaselineOptions & {
261
+ out: string;
262
+ };
263
+ type BreakageBaseline = {
264
+ version: 1;
265
+ tagPattern: string | null;
266
+ packageDirectory: string;
267
+ ref: string;
268
+ commit: string;
269
+ };
270
+ /** Resolve and fetch a release without running tests or changing the worktree. */
271
+ export declare function breakagePrelude({ out, tagPattern, baseDirname }: BreakagePreludeOptions): Promise<BreakageBaseline>;
178
272
  export declare function npmCheck(config: NpmConfig, options?: {
179
273
  baseDirectory?: string;
180
274
  coverageOnly?: boolean;
@@ -183,6 +277,24 @@ export declare function npmTest(config: NpmConfig, selection: NpmTestSelection,
183
277
  baseDirectory?: string;
184
278
  }): Promise<NpmReport>;
185
279
  export declare function formatNpmReport(report: NpmReport): string;
280
+ type NpmMatrixLocation = {
281
+ rootDirectory?: string;
282
+ bundleDirectory?: string;
283
+ };
284
+ /** Audit all configured packages and prepare one immutable, portable archive bundle. */
285
+ export declare function npmPlan(config: NpmMatrixConfig, options?: NpmMatrixLocation): Promise<NpmPlan>;
286
+ /** Execute exactly one audited environment, producing failure evidence whenever the plan is valid. */
287
+ export declare function npmExecute(value: unknown, id: string, options?: NpmMatrixLocation): Promise<NpmReceipt>;
288
+ /** Verify source/config/archive identities and then require all planned execution receipts. */
289
+ export declare function npmVerify(value: unknown, receipts: readonly unknown[], options?: NpmMatrixLocation): Promise<NpmVerification>;
290
+ export declare function npmMatrix(value: unknown): {
291
+ include: {
292
+ id: string;
293
+ label: string;
294
+ packageName: string;
295
+ representative: string;
296
+ }[];
297
+ };
186
298
  export type BreakageOptions = {
187
299
  tagPattern?: string | undefined;
188
300
  baselineFile?: string | undefined;
@@ -228,5 +340,5 @@ export type BreakageOutcome = {
228
340
  export declare function breakage(options: BreakageOptions): Promise<BreakageOutcome & {
229
341
  summary: string;
230
342
  }>;
231
- export { type BreakageBaseline, type BreakageConfig, type BreakagePreludeOptions, type CommandResult, type NpmConfig, type NpmPeerEvidence, type NpmReport, type NpmRepresentativeResult, type NpmSuite, type NpmSuiteResult, type NpmTestSelection, type ReleaseConfig, type ReleaseDeltaContext, type ReleaseDeltaResolver, type ReleasePolicy, type ReleasePolicyFunction, type SemverPolicyOptions, type SupportChange, type VersionDelta, type VersionTransition, resolveReleaseDelta, semverPolicy, versionDelta, versionTransition };
343
+ export { type BreakageBaseline, type BreakageConfig, type BreakagePreludeOptions, type CommandResult, type NpmArchiveRequest, type NpmConfig, type NpmMatrixConfig, type NpmMatrixLabelContext, type NpmMatrixLocation, type NpmPeerEvidence, type NpmPlan, type NpmPrepareContext, type NpmReceipt, type NpmReport, type NpmRepresentativeResult, type NpmSuite, type NpmSuiteResult, type NpmTestSelection, type NpmVerification, type ReleaseConfig, type ReleaseDeltaContext, type ReleaseDeltaResolver, type ReleasePolicy, type ReleasePolicyFunction, type SemverPolicyOptions, type SupportChange, type VersionDelta, type VersionTransition, resolveReleaseDelta, semverPolicy, versionDelta, versionTransition };
232
344
  //# sourceMappingURL=breakage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"breakage.d.ts","names":["_$__release_ts0.ReleaseDeltaResolver","_$__release_ts0.ReleasePolicyFunction","_$___release_ts0.ReleaseDeltaResolver","_$___release_ts0.ReleasePolicyFunction"],"sources":["../src/config.ts","../src/task.ts","../src/baseline.ts","../src/npm/config.ts","../src/npm/types.ts","../src/npm/check.ts","../src/breakage.ts"],"mappings":";;;;cAuCa;;;;;;;;;;;;M,eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAYD,iBAAiB,mBAAmB;;wBAGhC,aAAa,QAAQ,iBAAiB;;wBA8DhC,WAAW,mBAAmB,QAAQ;KCjHhD;EAAkB;EAAc;;KCOhC;EACX;EACA;;KAGW,yBAAyB;EAAoB;;KAE7C;EACX;EACA;EACA;EACA;EACA;;;wBAoBqB,kBACrB,KACA,YACA,eACE,yBAAyB,QAAQ;cCtCvB,8DAAc;;;;cAKd,+DAAe;;I,eAAfE;;;;;;;;;;;;;;;;;;;;;;;;;;;;KCXD;EACX;EACA;EACA;EACA;;KAGW,kBAAA,eAAuD;KACvD,mBAAA,gBAAyD;KAEzD;EACP;EAAc;;EACd;;KAEO;EACX;EACA;EACA;EACA;;KAGW;EACX;EACA;EACA;;KAGW;EACX;EACA;EAMA,OAAO,eAAe;EACtB,QAAQ;EACR;EACA;;KAGW;EACX;IAAW;IAAc;;EACzB;EACA;EACA,iBAAiB;EACjB;IAAY;IAAc;IAAa;;EACvC;IACC;IAOA,SAAS;IACT;IACA,UAAU;IACV;;EAED;;wBCwUqB,SACrB,QAAQ,WACR;EAAW;EAAwB;IACjC,QAAQ;wBAQW,QACrB,QAAQ,WACR,WAAW,kBACX;EAAW;IACT,QAAQ;wBASK,gBAAgB,QAAQ;YCvW5B;EACX;EACA;EACA;EACA;;EAEA;EACA,UAAU;EACV;EACA;;YAGW;EACP;;EACA;EAAmB;;EAErB;EACA;;EAGA;EACA;EACA;EACA;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;;EAGV;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;;wBAGS,SACrB,SAAS,kBACP,QAAQ;EAAoB"}
1
+ {"version":3,"file":"breakage.d.ts","names":["_$___release_ts0.ReleaseDeltaResolver","_$___release_ts0.ReleasePolicyFunction","_$__release_ts0.ReleaseDeltaResolver","_$__release_ts0.ReleasePolicyFunction","_$__npm_matrix_model_ts0.NpmPrepareContext","_$__npm_matrix_model_ts0.NpmMatrixLabelContext"],"sources":["../src/npm/config.ts","../src/npm/types.ts","../src/npm/matrix-model.ts","../src/config.ts","../src/task.ts","../src/baseline.ts","../src/npm/check.ts","../src/npm/matrix.ts","../src/breakage.ts"],"mappings":";;;cAQa,8DAAc;;;;cAKd,+DAAe;;I,eAAfA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KCXD;EACX;EACA;EACA;EACA;;KAGW,kBAAA,eAAuD;KACvD,mBAAA,gBAAyD;KAEzD;EACP;EAAc;;EACd;;KAEO;EACX;EACA;EACA;EACA;;KAGW;EACX;EACA;EACA;;KAGW;EACX;EACA;EAMA,OAAO,eAAe;EACtB,QAAQ;EACR;EACA;;KAGW;EACX;IAAW;IAAc;;EACzB;EACA;EACA,iBAAiB;EACjB;IAAY;IAAc;IAAa;;EACvC;IACC;IAOA,SAAS;IACT;IACA,UAAU;IACV;;EAED;;KCzDW;EACX;EACA;EACA;;KAEW;EACX;EACA,UAAU;;KAEC;EACX;EACA;EACA;EACA,OAAO,eAAe;;cAEV,qEAAqB;;EAIF,oBAAA,SAAA,6BAA6B;EAEpB,SAAA,SAAA;;KAE7B,yBAAyB,sBAAsB;cAiD9C,6DAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAsCd,iBAAiB,cAAc;cAC9B,gEAAgB;;;;;;;;KASjB,oBAAoB,iBAAiB;KACrC;EACX;EACA;EACA;;;wBAwKe,kBACf,gBACA,+BACE;;cCnQU;;;;;;;;;;;;M,eAAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAaD,iBAAiB,mBAAmB;;wBAGhC,aAAa,QAAQ,iBAAiB;;wBA8DhC,WAAW,mBAAmB,QAAQ;KCpHhD;EAAkB;EAAc;;KCOhC;EACX;EACA;;KAGW,yBAAyB;EAAoB;;KAE7C;EACX;EACA;EACA;EACA;EACA;;;wBAoBqB,kBACrB,KACA,YACA,eACE,yBAAyB,QAAQ;wBC4Vd,SACrB,QAAQ,WACR;EAAW;EAAwB;IACjC,QAAQ;wBAQW,QACrB,QAAQ,WACR,WAAW,kBACX;EAAW;IACT,QAAQ;wBAwBK,gBAAgB,QAAQ;KC5X5B;EACX;EACA;;;wBAsOqB,QACrB,QAAQ,iBACR,UAAS,oBACP,QAAQ;;wBAyPW,WACrB,gBACA,YACA,UAAS,oBACP,QAAQ;;wBAmEW,UACrB,gBACA,8BACA,UAAS,oBACP,QAAQ;wBAUK,UAAU;EACzB;IACC;IACA;IACA;IACA;;;YC3iBU;EACX;EACA;EACA;EACA;;EAEA;EACA,UAAU;EACV;EACA;;YAGW;EACP;;EACA;EAAmB;;EAErB;EACA;;EAGA;EACA;EACA;EACA;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;;EAGV;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;;wBAGS,SACrB,SAAS,kBACP,QAAQ;EAAoB"}
package/dist/breakage.js CHANGED
@@ -1,3 +1,3 @@
1
- import { d as loadConfig, i as npmTest, m as breakagePrelude, n as formatNpmReport, r as npmCheck, t as breakage, u as defineConfig } from "./breakage-DIY49fzP.js";
1
+ import { a as npmVerify, b as breakagePrelude, c as npmCheck, g as loadConfig, h as defineConfig, i as npmPlan, l as npmTest, n as npmExecute, r as npmMatrix, s as formatNpmReport, t as breakage, v as verifyNpmReceipts } from "./breakage-DJiIiLzL.js";
2
2
  import { i as semverPolicy, o as versionDelta, r as resolveReleaseDelta, s as versionTransition } from "./release-BsdIDT4g.js";
3
- export { breakage, breakagePrelude, defineConfig, formatNpmReport, loadConfig, npmCheck, npmTest, resolveReleaseDelta, semverPolicy, versionDelta, versionTransition };
3
+ export { breakage, breakagePrelude, defineConfig, formatNpmReport, loadConfig, npmCheck, npmExecute, npmMatrix, npmPlan, npmTest, npmVerify, resolveReleaseDelta, semverPolicy, verifyNpmReceipts, versionDelta, versionTransition };
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { a as configFields, c as configSchema, d as loadConfig, f as resolveConfig, h as errorMessage, i as npmTest, l as defaultConfig, m as breakagePrelude, n as formatNpmReport, o as configOptions, p as validateConfig, r as npmCheck, s as configPath, t as breakage } from "./breakage-DIY49fzP.js";
2
+ import { _ as resolveConfig, a as npmVerify, b as breakagePrelude, c as npmCheck, d as configOptions, f as configPath, g as loadConfig, i as npmPlan, l as npmTest, m as defaultConfig, n as npmExecute, o as writeMatrixJson, p as configSchema, r as npmMatrix, s as formatNpmReport, t as breakage, u as configFields, x as errorMessage, y as validateConfig } from "./breakage-DJiIiLzL.js";
3
3
  import path from "node:path";
4
4
  import logger from "takua";
5
+ import { glob, readFile } from "node:fs/promises";
5
6
  import { type } from "arktype";
6
7
  import { cli, completionResponse, encapsulate, help, logWarnings, noOptions, optional, options, parseBooleanOption, required } from "comline";
7
8
  import { inspect } from "node:util";
@@ -9,6 +10,7 @@ import { inspect } from "node:util";
9
10
  const common = {
10
11
  release: configOptions.optionConfigs.release,
11
12
  npm: configOptions.optionConfigs.npm,
13
+ npmMatrix: configOptions.optionConfigs.npmMatrix,
12
14
  config: {
13
15
  schema: type(`string`),
14
16
  required: false,
@@ -32,7 +34,8 @@ const npmCheckManual = options(`Check npm peer compatibility and changes in decl
32
34
  "json?": `boolean`,
33
35
  "coverageOnly?": `boolean`,
34
36
  "release?": configOptions.optionsSchema.get(`release`),
35
- "npm?": configOptions.optionsSchema.get(`npm`)
37
+ "npm?": configOptions.optionsSchema.get(`npm`),
38
+ "npmMatrix?": configOptions.optionsSchema.get(`npmMatrix`)
36
39
  }), {
37
40
  ...common,
38
41
  coverageOnly: {
@@ -49,7 +52,8 @@ const npmTestManual = options(`Run current contracts in matching complete peer e
49
52
  "json?": `boolean`,
50
53
  "representative?": `string`,
51
54
  "release?": configOptions.optionsSchema.get(`release`),
52
- "npm?": configOptions.optionsSchema.get(`npm`)
55
+ "npm?": configOptions.optionsSchema.get(`npm`),
56
+ "npmMatrix?": configOptions.optionsSchema.get(`npmMatrix`)
53
57
  }), {
54
58
  ...common,
55
59
  representative: {
@@ -90,11 +94,131 @@ async function runNpmCli(action, opts, peerSelection) {
90
94
  return 2;
91
95
  }
92
96
  }
97
+ // src/npm/matrix-cli.ts
98
+ const hiddenSchema = {
99
+ "release?": configOptions.optionsSchema.get(`release`),
100
+ "npm?": configOptions.optionsSchema.get(`npm`),
101
+ "npmMatrix?": configOptions.optionsSchema.get(`npmMatrix`)
102
+ };
103
+ const hidden = {
104
+ release: { configOnly: true },
105
+ npm: { configOnly: true },
106
+ npmMatrix: { configOnly: true }
107
+ };
108
+ const root = {
109
+ schema: type(`string`),
110
+ required: false,
111
+ description: `Source Git checkout root (defaults to the current directory).`,
112
+ example: `--root .`,
113
+ completion: { fileSystem: `directories` }
114
+ };
115
+ const plan = {
116
+ schema: type(`string`),
117
+ required: true,
118
+ description: `Prepared plan.json; archives are read from its bundle directory.`,
119
+ example: `--plan .breakage/npm-plan/plan.json`,
120
+ completion: { fileSystem: `files` }
121
+ };
122
+ const npmPlanManual = options(`Audit the peer matrix and prepare a portable archive bundle; print matrix JSON.`, type({
123
+ ...hiddenSchema,
124
+ "config?": `string`,
125
+ "root?": `string`,
126
+ "out?": `string`
127
+ }), {
128
+ ...hidden,
129
+ root,
130
+ config: {
131
+ schema: type(`string`),
132
+ required: false,
133
+ description: `TypeScript configuration containing npmMatrix.`,
134
+ example: `--config breakage.config.ts`,
135
+ completion: { fileSystem: `files` }
136
+ },
137
+ out: {
138
+ schema: type(`string`),
139
+ required: false,
140
+ description: `Bundle directory (defaults to .breakage/npm-plan).`,
141
+ example: `--out .breakage/peer-bundle`,
142
+ completion: { fileSystem: `directories` }
143
+ }
144
+ });
145
+ const npmExecuteManual = options(`Execute one planned representative and write its receipt.`, type({
146
+ ...hiddenSchema,
147
+ plan: `string`,
148
+ receipt: `string`,
149
+ "root?": `string`
150
+ }), {
151
+ ...hidden,
152
+ root,
153
+ plan,
154
+ receipt: {
155
+ schema: type(`string`),
156
+ required: true,
157
+ description: `Output receipt filename.`,
158
+ example: `--receipt .breakage/receipts/environment.json`,
159
+ completion: { fileSystem: `files` }
160
+ }
161
+ });
162
+ const npmVerifyManual = options(`Verify the complete planned matrix against collected execution receipts.`, type({
163
+ ...hiddenSchema,
164
+ plan: `string`,
165
+ receipts: `string`,
166
+ "root?": `string`
167
+ }), {
168
+ ...hidden,
169
+ root,
170
+ plan,
171
+ receipts: {
172
+ schema: type(`string`),
173
+ required: true,
174
+ description: `Glob selecting all collected JSON receipts, relative to root.`,
175
+ example: `--receipts '.breakage/receipts/**/*.json'`,
176
+ completion: { fileSystem: `files` }
177
+ }
178
+ });
179
+ async function runNpmMatrixCli(action, opts, id) {
180
+ try {
181
+ const rootDirectory = path.resolve(opts.root ?? process.cwd());
182
+ if (action === `plan`) {
183
+ const config = await loadConfig(path.resolve(rootDirectory, opts.config ?? defaultConfig(rootDirectory)));
184
+ if (!config.npmMatrix) throw new Error(`Configure npmMatrix.configs and npmMatrix.prepare.`);
185
+ const prepared = await npmPlan(config.npmMatrix, {
186
+ rootDirectory,
187
+ ...opts.out ? { bundleDirectory: opts.out } : {}
188
+ });
189
+ process.stdout.write(`${JSON.stringify(npmMatrix(prepared))}\n`);
190
+ return 0;
191
+ }
192
+ const filename = path.resolve(rootDirectory, opts.plan);
193
+ const value = JSON.parse(await readFile(filename, `utf8`));
194
+ const location = {
195
+ rootDirectory,
196
+ bundleDirectory: path.dirname(filename)
197
+ };
198
+ if (action === `execute`) {
199
+ const receipt = await npmExecute(value, id, location);
200
+ await writeMatrixJson(path.resolve(rootDirectory, opts.receipt), receipt);
201
+ if (receipt.report) process.stdout.write(formatNpmReport(receipt.report));
202
+ if (receipt.error) process.stderr.write(`${receipt.error}\n`);
203
+ return receipt.exitCode;
204
+ }
205
+ const receipts = [];
206
+ for await (const filename of glob(opts.receipts, { cwd: rootDirectory })) receipts.push(JSON.parse(await readFile(path.resolve(rootDirectory, filename), `utf8`)));
207
+ const result = await npmVerify(value, receipts, location);
208
+ if (result.errors.length) process.stderr.write(`${result.errors.join(`\n`)}\n`);
209
+ else process.stdout.write(`Verified passing receipts for all ${result.environments} planned environments.\n`);
210
+ return result.exitCode;
211
+ } catch (error) {
212
+ process.stderr.write(`npm matrix setup error: ${errorMessage(error)}\n`);
213
+ return 2;
214
+ }
215
+ }
93
216
  // src/breakage.x.ts
94
217
  const commandOverrides = /* @__PURE__ */ new Set();
95
218
  const BREAKAGE_MANUAL = options(`Check for breaking changes in a package.`, configSchema, {
96
219
  release: { configOnly: true },
97
220
  npm: { configOnly: true },
221
+ npmMatrix: { configOnly: true },
98
222
  out: { configOnly: true },
99
223
  tagPattern: {
100
224
  schema: configFields.tagPattern,
@@ -207,6 +331,9 @@ const parse = cli({
207
331
  npm: optional({
208
332
  help: null,
209
333
  check: null,
334
+ plan: null,
335
+ execute: required({ $id: null }),
336
+ verify: null,
210
337
  test: optional({ $peer: required({ $range: null }) })
211
338
  }),
212
339
  prelude: optional({ $configPath: null }),
@@ -219,6 +346,9 @@ const parse = cli({
219
346
  npm: noOptions(`Show npm compatibility commands.`),
220
347
  "npm/help": noOptions(`Show npm compatibility commands.`),
221
348
  "npm/check": npmCheckManual,
349
+ "npm/plan": npmPlanManual,
350
+ "npm/execute/$id": npmExecuteManual,
351
+ "npm/verify": npmVerifyManual,
222
352
  "npm/test": npmTestManual,
223
353
  "npm/test/$peer/$range": npmTestManual,
224
354
  prelude: PRELUDE_MANUAL,
@@ -247,6 +377,15 @@ else try {
247
377
  case `npm/check`:
248
378
  process.exitCode = await runNpmCli(`check`, inputs.opts);
249
379
  break;
380
+ case `npm/plan`:
381
+ process.exitCode = await runNpmMatrixCli(`plan`, inputs.opts);
382
+ break;
383
+ case `npm/execute/$id`:
384
+ process.exitCode = await runNpmMatrixCli(`execute`, inputs.opts, inputs.params.id);
385
+ break;
386
+ case `npm/verify`:
387
+ process.exitCode = await runNpmMatrixCli(`verify`, inputs.opts);
388
+ break;
250
389
  case `npm/test`:
251
390
  process.exitCode = await runNpmCli(`test`, inputs.opts);
252
391
  break;
@@ -1 +1 @@
1
- {"version":3,"file":"breakage.x.js","names":[],"sources":["../src/npm/cli.ts","../src/breakage.x.ts"],"sourcesContent":["import path from \"node:path\"\n\nimport { type } from \"arktype\"\nimport type { OptionsGroup } from \"comline\"\nimport { options, parseBooleanOption } from \"comline\"\n\nimport { configOptions, defaultConfig, loadConfig } from \"../config.ts\"\n\nimport { formatNpmReport, npmCheck, npmTest } from \"./check.ts\"\nimport { errorMessage } from \"../task.ts\"\nimport { validateConfig } from \"./config.ts\"\nimport type { NpmTestSelection } from \"./types.ts\"\n\ntype CommonOptions = {\n\tconfig?: string | undefined\n\tjson?: boolean | undefined\n\trelease?: import(\"../release.ts\").ReleaseConfig\n\tnpm?: import(\"./types.ts\").NpmConfig\n}\ntype CheckOptions = CommonOptions & { coverageOnly?: boolean | undefined }\ntype TestOptions = CommonOptions & { representative?: string | undefined }\n\nconst common = {\n\trelease: configOptions.optionConfigs.release,\n\tnpm: configOptions.optionConfigs.npm,\n\tconfig: {\n\t\tschema: type(`string`),\n\t\trequired: false,\n\t\tdescription: `Configuration file (defaults to breakage.config.ts).`,\n\t\texample: `--config ./breakage.config.ts`,\n\t\tcompletion: { fileSystem: `files` as const, repeatable: false },\n\t},\n\tjson: {\n\t\tschema: type(`boolean`),\n\t\trequired: false,\n\t\tdescription: `Emit the structured result.`,\n\t\texample: `--json`,\n\t\tparse: parseBooleanOption,\n\t},\n}\n\nexport const npmCheckManual: OptionsGroup<CheckOptions> = options(\n\t`Check npm peer compatibility and changes in declared support.`,\n\ttype({\n\t\t\"config?\": `string`,\n\t\t\"json?\": `boolean`,\n\t\t\"coverageOnly?\": `boolean`,\n\t\t\"release?\": configOptions.optionsSchema.get(`release`),\n\t\t\"npm?\": configOptions.optionsSchema.get(`npm`),\n\t}),\n\t{\n\t\t...common,\n\t\tcoverageOnly: {\n\t\t\tschema: type(`boolean`),\n\t\t\taliases: [`coverage-only`],\n\t\t\trequired: false,\n\t\t\tdescription: `Audit coverage and support changes without executing assertions.`,\n\t\t\texample: `--coverage-only`,\n\t\t\tparse: parseBooleanOption,\n\t\t},\n\t},\n)\n\nexport const npmTestManual: OptionsGroup<TestOptions> = options(\n\t`Run current contracts in matching complete peer environments.`,\n\ttype({\n\t\t\"config?\": `string`,\n\t\t\"json?\": `boolean`,\n\t\t\"representative?\": `string`,\n\t\t\"release?\": configOptions.optionsSchema.get(`release`),\n\t\t\"npm?\": configOptions.optionsSchema.get(`npm`),\n\t}),\n\t{\n\t\t...common,\n\t\trepresentative: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: false,\n\t\t\tdescription: `Select an exact configured representative path relative to the package.`,\n\t\t\texample: `--representative peer-environments/react-19`,\n\t\t\tcompletion: { fileSystem: `directories`, repeatable: false },\n\t\t},\n\t},\n)\n\nexport async function runNpmCli(\n\taction: `check` | `test`,\n\topts: CheckOptions & TestOptions,\n\tpeerSelection?: { peer: string; range: string },\n): Promise<number> {\n\ttry {\n\t\tconst filename = path.resolve(opts.config ?? defaultConfig(process.cwd()))\n\t\tconst config = (await loadConfig(filename)).npm\n\t\tvalidateConfig(config)\n\t\tlet selection: NpmTestSelection | undefined\n\t\tif (action === `test`) {\n\t\t\tif (peerSelection && opts.representative)\n\t\t\t\tthrow new Error(`Choose a peer range or a representative, not both.`)\n\t\t\tselection =\n\t\t\t\tpeerSelection ??\n\t\t\t\t(opts.representative\n\t\t\t\t\t? { representative: opts.representative }\n\t\t\t\t\t: undefined)\n\t\t\tif (!selection)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Use npm test <peer> <range> or npm test --representative <path>.`,\n\t\t\t\t)\n\t\t}\n\t\tconst options = {\n\t\t\tbaseDirectory: path.dirname(filename),\n\t\t\tcoverageOnly: opts.coverageOnly ?? false,\n\t\t}\n\t\tconst report = selection\n\t\t\t? await npmTest(config, selection, options)\n\t\t\t: await npmCheck(config, options)\n\t\tprocess.stdout.write(\n\t\t\topts.json\n\t\t\t\t? `${JSON.stringify(report, null, 2)}\\n`\n\t\t\t\t: formatNpmReport(report),\n\t\t)\n\t\treturn report.exitCode\n\t} catch (error) {\n\t\tconst message = errorMessage(error)\n\t\tprocess.stdout.write(\n\t\t\topts.json\n\t\t\t\t? `${JSON.stringify({ exitCode: 2, errors: [message] })}\\n`\n\t\t\t\t: `npm setup error: ${message}\\n`,\n\t\t)\n\t\treturn 2\n\t}\n}\n","#!/usr/bin/env node\n\nimport path from \"node:path\"\nimport { inspect } from \"node:util\"\n\nimport {\n\tcli,\n\tcompletionResponse,\n\tencapsulate,\n\thelp,\n\tlogWarnings,\n\tnoOptions,\n\toptional,\n\toptions,\n\tparseBooleanOption,\n\trequired,\n} from \"comline\"\nimport logger from \"takua\"\n\nimport {\n\tdefaultConfig,\n\tconfigPath,\n\tresolveConfig,\n\tconfigSchema,\n\tconfigFields,\n} from \"./config.ts\"\nimport { breakage, breakagePrelude } from \"./breakage.ts\"\nimport { errorMessage } from \"./task.ts\"\nimport { npmCheckManual, npmTestManual, runNpmCli } from \"./npm/cli.ts\"\n\n// Either command spelling can override the other spelling in a config file.\nconst commandOverrides = new Set<`test` | `testCommand`>()\n\nconst BREAKAGE_MANUAL = options(\n\t`Check for breaking changes in a package.`,\n\tconfigSchema,\n\t{\n\t\trelease: { configOnly: true },\n\t\tnpm: { configOnly: true },\n\t\tout: { configOnly: true },\n\t\ttagPattern: {\n\t\t\tschema: configFields.tagPattern,\n\t\t\taliases: [`tag-pattern`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `g`,\n\t\t\trequired: false,\n\t\t\tdescription: `RegExp which, if found matched to a git tag, will be considered a release tag for your library.`,\n\t\t\texample: `--tagPattern=\"my-library\"`,\n\t\t},\n\t\tbaselineFile: {\n\t\t\tschema: configFields.baselineFile,\n\t\t\taliases: [`baseline-file`],\n\t\t\tcompletion: { repeatable: false, fileSystem: `files` },\n\t\t\trequired: false,\n\t\t\tdescription: `Use the exact locally fetched commit from a prelude snapshot instead of discovering remote tags.`,\n\t\t\texample: `--baseline-file=.breakage/baseline.json`,\n\t\t},\n\t\ttestPattern: {\n\t\t\tschema: configFields.testPattern,\n\t\t\taliases: [`test-pattern`, `pattern`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `p`,\n\t\t\trequired: false,\n\t\t\tdescription: `The pattern to match test files that test the public API of the library.`,\n\t\t\texample: `--pattern=\"*__public.test.ts\"`,\n\t\t},\n\t\ttestCommand: {\n\t\t\tparse: (value) => {\n\t\t\t\tcommandOverrides.add(`testCommand`)\n\t\t\t\treturn value\n\t\t\t},\n\t\t\tschema: configFields.testCommand,\n\t\t\taliases: [`test-command`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `t`,\n\t\t\trequired: false,\n\t\t\tdescription: `Complete bash command that runs the tests for the library's public API.`,\n\t\t\texample: `--testCommand=\"npm run test\"`,\n\t\t},\n\t\ttest: {\n\t\t\tparse: (value) => {\n\t\t\t\tcommandOverrides.add(`test`)\n\t\t\t\treturn value\n\t\t\t},\n\t\t\tschema: configFields.test,\n\t\t\tcompletion: { repeatable: false },\n\t\t\trequired: false,\n\t\t\tdescription: `Shell command running the restored public contracts.`,\n\t\t\texample: `--test=\"npm run test:public\"`,\n\t\t},\n\t\tbaseDirname: {\n\t\t\tparse: (value) => path.resolve(value),\n\t\t\tschema: configFields.baseDirname,\n\t\t\taliases: [`base-dir`, `base-dirname`],\n\t\t\tcompletion: { repeatable: false, fileSystem: `directories` },\n\t\t\tflag: `d`,\n\t\t\trequired: false,\n\t\t\tdescription: `The base directory to run the command from.`,\n\t\t\texample: `--baseDirname=./packages/my-package`,\n\t\t},\n\t\tverbose: {\n\t\t\tschema: configFields.verbose,\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `v`,\n\t\t\trequired: false,\n\t\t\tdescription: `Prints out more information about the process.`,\n\t\t\texample: `--verbose`,\n\t\t\tparse: parseBooleanOption,\n\t\t},\n\t},\n)\n\nconst PRELUDE_MANUAL = options(\n\t`Resolve and fetch the release baseline for a cacheable compatibility check.`,\n\tconfigSchema,\n\t{\n\t\t...BREAKAGE_MANUAL.optionConfigs,\n\t\ttestPattern: {\n\t\t\t...BREAKAGE_MANUAL.optionConfigs.testPattern,\n\t\t\trequired: false,\n\t\t},\n\t\ttestCommand: {\n\t\t\t...BREAKAGE_MANUAL.optionConfigs.testCommand,\n\t\t\trequired: false,\n\t\t},\n\t\tout: {\n\t\t\tschema: configFields.out,\n\t\t\tcompletion: { repeatable: false, fileSystem: `files` },\n\t\t\trequired: false,\n\t\t\tdescription: `Gitignored snapshot path relative to the base directory (default: .breakage/baseline.json).`,\n\t\t\texample: `--out=.breakage/baseline.json`,\n\t\t},\n\t},\n)\n\nlet loadedConfigPath: string | undefined\nconst parse = cli(\n\t{\n\t\tcliName: `breakage`,\n\t\tdiscoverConfigPath: (segments: readonly string[]) => {\n\t\t\tif (segments[0] === `help` || segments[0] === `npm`) return undefined\n\t\t\tconst explicit = segments[0] === `prelude` ? segments[1] : segments[0]\n\t\t\tloadedConfigPath = configPath(\n\t\t\t\texplicit ?? defaultConfig(process.cwd()),\n\t\t\t\texplicit !== undefined,\n\t\t\t)\n\t\t\treturn loadedConfigPath\n\t\t},\n\t\troutes: optional({\n\t\t\thelp: null,\n\t\t\tnpm: optional({\n\t\t\t\thelp: null,\n\t\t\t\tcheck: null,\n\t\t\t\ttest: optional({ $peer: required({ $range: null }) }),\n\t\t\t}),\n\t\t\tprelude: optional({ $configPath: null }),\n\t\t\t$configPath: null,\n\t\t}),\n\t\trouteOptions: {\n\t\t\t\"\": BREAKAGE_MANUAL,\n\t\t\t$configPath: BREAKAGE_MANUAL,\n\t\t\thelp: noOptions(`Show usage.`),\n\t\t\tnpm: noOptions(`Show npm compatibility commands.`),\n\t\t\t\"npm/help\": noOptions(`Show npm compatibility commands.`),\n\t\t\t\"npm/check\": npmCheckManual,\n\t\t\t\"npm/test\": npmTestManual,\n\t\t\t\"npm/test/$peer/$range\": npmTestManual,\n\t\t\tprelude: PRELUDE_MANUAL,\n\t\t\t\"prelude/$configPath\": PRELUDE_MANUAL,\n\t\t},\n\t\tpositionalCompletions: {\n\t\t\t$configPath: { fileSystem: `files` },\n\t\t\t\"prelude/$configPath\": { fileSystem: `files` },\n\t\t},\n\t},\n\t{\n\t\tinfo: (message, ...data) => logger.info(`breakage`, message, data),\n\t\terror: (message, ...data) => logger.error(`breakage`, message, data),\n\t},\n)\n\nconst completion = await completionResponse(parse.definition, process.argv)\nif (completion !== undefined) {\n\tprocess.stdout.write(completion)\n} else {\n\ttry {\n\t\tconst { inputs, warnings } = await parse.async(process.argv)\n\t\tlogWarnings(warnings)\n\t\tif (\n\t\t\tprocess.argv\n\t\t\t\t.slice(2)\n\t\t\t\t.some((arg) =>\n\t\t\t\t\t/^(?:--certifyCommand|--certify-command|-c)(?:=|$)/.test(arg),\n\t\t\t\t)\n\t\t)\n\t\t\tthrow new Error(\n\t\t\t\t`certifyCommand was removed. Configure release.resolveDelta and release.policy instead.`,\n\t\t\t)\n\n\t\tswitch (inputs.case) {\n\t\t\tcase `npm`:\n\t\t\tcase `npm/help`:\n\t\t\tcase `help`:\n\t\t\t\tconsole.log(help(parse.definition))\n\t\t\t\tbreak\n\t\t\tcase `npm/check`:\n\t\t\t\tprocess.exitCode = await runNpmCli(`check`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/test`:\n\t\t\t\tprocess.exitCode = await runNpmCli(`test`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/test/$peer/$range`:\n\t\t\t\tprocess.exitCode = await runNpmCli(`test`, inputs.opts, inputs.params)\n\t\t\t\tbreak\n\t\t\tcase `prelude`:\n\t\t\tcase `prelude/$configPath`: {\n\t\t\t\tconst config = resolveConfig(inputs.opts, loadedConfigPath)\n\t\t\t\tconst baseline = await breakagePrelude({\n\t\t\t\t\t...config,\n\t\t\t\t\tout: config.out ?? `.breakage/baseline.json`,\n\t\t\t\t})\n\t\t\t\tprocess.stdout.write(`Pinned ${baseline.ref} at ${baseline.commit}.\\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase ``:\n\t\t\tcase `$configPath`: {\n\t\t\t\tconst merged = resolveConfig(inputs.opts, loadedConfigPath)\n\t\t\t\tif (\n\t\t\t\t\tcommandOverrides.has(`testCommand`) &&\n\t\t\t\t\t!commandOverrides.has(`test`)\n\t\t\t\t)\n\t\t\t\t\tdelete merged.test\n\t\t\t\tif (\n\t\t\t\t\tcommandOverrides.has(`test`) &&\n\t\t\t\t\t!commandOverrides.has(`testCommand`)\n\t\t\t\t)\n\t\t\t\t\tdelete merged.testCommand\n\t\t\t\tif (!merged.testPattern)\n\t\t\t\t\tthrow new Error(`required arguments were not provided: testPattern.`)\n\t\t\t\tconst { returnValue } = await encapsulate(\n\t\t\t\t\t() =>\n\t\t\t\t\t\tbreakage({\n\t\t\t\t\t\t\t...merged,\n\t\t\t\t\t\t\ttestPattern: merged.testPattern!,\n\t\t\t\t\t\t}),\n\t\t\t\t\t{\n\t\t\t\t\t\tconsole: true,\n\t\t\t\t\t\tstdout: true,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\tif (`release` in returnValue && returnValue.release) {\n\t\t\t\t\tconst { previousVersion, version, delta, breaking } =\n\t\t\t\t\t\treturnValue.release\n\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t`Release: ${previousVersion} → ${version} (${delta}; ${breaking ? `breaking` : `compatible`}).\\n`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (`testResult` in returnValue && returnValue.breakingChangesFound) {\n\t\t\t\t\tprocess.stdout.write(returnValue.testResult)\n\t\t\t\t}\n\t\t\t\tif (`breakingChangesFound` in returnValue) {\n\t\t\t\t\tif (returnValue.breakingChangesFound) {\n\t\t\t\t\t\tif (returnValue.release?.breaking) {\n\t\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t\t`👷 Breaking changes are covered by the breaking release.`,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tprocess.exit(0)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t\t`❌ Breaking changes require a breaking release.`,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tprocess.exit(1)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprocess.stdout.write(`✅ No breaking changes were found.`)\n\t\t\t\t\t\tprocess.exit(0)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t`💥 Breakage failed to determine breaking changes.` +\n\t\t\t\t\t\t\t`\\n` +\n\t\t\t\t\t\t\tinspect(returnValue),\n\t\t\t\t\t)\n\t\t\t\t\tprocess.exit(2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tprocess.stderr.write(`Breakage setup error: ${errorMessage(error)}\\n`)\n\t\tprocess.exitCode = 2\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"breakage.x.js","names":[],"sources":["../src/npm/cli.ts","../src/npm/matrix-cli.ts","../src/breakage.x.ts"],"sourcesContent":["import path from \"node:path\"\n\nimport { type } from \"arktype\"\nimport type { OptionsGroup } from \"comline\"\nimport { options, parseBooleanOption } from \"comline\"\n\nimport { configOptions, defaultConfig, loadConfig } from \"../config.ts\"\n\nimport { formatNpmReport, npmCheck, npmTest } from \"./check.ts\"\nimport { errorMessage } from \"../task.ts\"\nimport { validateConfig } from \"./config.ts\"\nimport type { NpmTestSelection } from \"./types.ts\"\n\ntype CommonOptions = {\n\tconfig?: string | undefined\n\tjson?: boolean | undefined\n\trelease?: import(\"../release.ts\").ReleaseConfig\n\tnpm?: import(\"./types.ts\").NpmConfig\n\tnpmMatrix?: import(\"./matrix-model.ts\").NpmMatrixConfig\n}\ntype CheckOptions = CommonOptions & { coverageOnly?: boolean | undefined }\ntype TestOptions = CommonOptions & { representative?: string | undefined }\n\nconst common = {\n\trelease: configOptions.optionConfigs.release,\n\tnpm: configOptions.optionConfigs.npm,\n\tnpmMatrix: configOptions.optionConfigs.npmMatrix,\n\tconfig: {\n\t\tschema: type(`string`),\n\t\trequired: false,\n\t\tdescription: `Configuration file (defaults to breakage.config.ts).`,\n\t\texample: `--config ./breakage.config.ts`,\n\t\tcompletion: { fileSystem: `files` as const, repeatable: false },\n\t},\n\tjson: {\n\t\tschema: type(`boolean`),\n\t\trequired: false,\n\t\tdescription: `Emit the structured result.`,\n\t\texample: `--json`,\n\t\tparse: parseBooleanOption,\n\t},\n}\n\nexport const npmCheckManual: OptionsGroup<CheckOptions> = options(\n\t`Check npm peer compatibility and changes in declared support.`,\n\ttype({\n\t\t\"config?\": `string`,\n\t\t\"json?\": `boolean`,\n\t\t\"coverageOnly?\": `boolean`,\n\t\t\"release?\": configOptions.optionsSchema.get(`release`),\n\t\t\"npm?\": configOptions.optionsSchema.get(`npm`),\n\t\t\"npmMatrix?\": configOptions.optionsSchema.get(`npmMatrix`),\n\t}),\n\t{\n\t\t...common,\n\t\tcoverageOnly: {\n\t\t\tschema: type(`boolean`),\n\t\t\taliases: [`coverage-only`],\n\t\t\trequired: false,\n\t\t\tdescription: `Audit coverage and support changes without executing assertions.`,\n\t\t\texample: `--coverage-only`,\n\t\t\tparse: parseBooleanOption,\n\t\t},\n\t},\n)\n\nexport const npmTestManual: OptionsGroup<TestOptions> = options(\n\t`Run current contracts in matching complete peer environments.`,\n\ttype({\n\t\t\"config?\": `string`,\n\t\t\"json?\": `boolean`,\n\t\t\"representative?\": `string`,\n\t\t\"release?\": configOptions.optionsSchema.get(`release`),\n\t\t\"npm?\": configOptions.optionsSchema.get(`npm`),\n\t\t\"npmMatrix?\": configOptions.optionsSchema.get(`npmMatrix`),\n\t}),\n\t{\n\t\t...common,\n\t\trepresentative: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: false,\n\t\t\tdescription: `Select an exact configured representative path relative to the package.`,\n\t\t\texample: `--representative peer-environments/react-19`,\n\t\t\tcompletion: { fileSystem: `directories`, repeatable: false },\n\t\t},\n\t},\n)\n\nexport async function runNpmCli(\n\taction: `check` | `test`,\n\topts: CheckOptions & TestOptions,\n\tpeerSelection?: { peer: string; range: string },\n): Promise<number> {\n\ttry {\n\t\tconst filename = path.resolve(opts.config ?? defaultConfig(process.cwd()))\n\t\tconst config = (await loadConfig(filename)).npm\n\t\tvalidateConfig(config)\n\t\tlet selection: NpmTestSelection | undefined\n\t\tif (action === `test`) {\n\t\t\tif (peerSelection && opts.representative)\n\t\t\t\tthrow new Error(`Choose a peer range or a representative, not both.`)\n\t\t\tselection =\n\t\t\t\tpeerSelection ??\n\t\t\t\t(opts.representative\n\t\t\t\t\t? { representative: opts.representative }\n\t\t\t\t\t: undefined)\n\t\t\tif (!selection)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Use npm test <peer> <range> or npm test --representative <path>.`,\n\t\t\t\t)\n\t\t}\n\t\tconst options = {\n\t\t\tbaseDirectory: path.dirname(filename),\n\t\t\tcoverageOnly: opts.coverageOnly ?? false,\n\t\t}\n\t\tconst report = selection\n\t\t\t? await npmTest(config, selection, options)\n\t\t\t: await npmCheck(config, options)\n\t\tprocess.stdout.write(\n\t\t\topts.json\n\t\t\t\t? `${JSON.stringify(report, null, 2)}\\n`\n\t\t\t\t: formatNpmReport(report),\n\t\t)\n\t\treturn report.exitCode\n\t} catch (error) {\n\t\tconst message = errorMessage(error)\n\t\tprocess.stdout.write(\n\t\t\topts.json\n\t\t\t\t? `${JSON.stringify({ exitCode: 2, errors: [message] })}\\n`\n\t\t\t\t: `npm setup error: ${message}\\n`,\n\t\t)\n\t\treturn 2\n\t}\n}\n","import { glob, readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { type } from \"arktype\"\nimport { options } from \"comline\"\nimport { configOptions, defaultConfig, loadConfig } from \"../config.ts\"\nimport { errorMessage } from \"../task.ts\"\nimport { formatNpmReport } from \"./check.ts\"\nimport {\n\tnpmPlan,\n\tnpmExecute,\n\tnpmVerify,\n\tnpmMatrix,\n\twriteMatrixJson,\n} from \"./matrix.ts\"\n\nconst hiddenSchema = {\n\t\"release?\": configOptions.optionsSchema.get(`release`),\n\t\"npm?\": configOptions.optionsSchema.get(`npm`),\n\t\"npmMatrix?\": configOptions.optionsSchema.get(`npmMatrix`),\n}\nconst hidden = {\n\trelease: { configOnly: true },\n\tnpm: { configOnly: true },\n\tnpmMatrix: { configOnly: true },\n} as const\nconst root = {\n\tschema: type(`string`),\n\trequired: false,\n\tdescription: `Source Git checkout root (defaults to the current directory).`,\n\texample: `--root .`,\n\tcompletion: { fileSystem: `directories` as const },\n}\nconst plan = {\n\tschema: type(`string`),\n\trequired: true,\n\tdescription: `Prepared plan.json; archives are read from its bundle directory.`,\n\texample: `--plan .breakage/npm-plan/plan.json`,\n\tcompletion: { fileSystem: `files` as const },\n}\n\nexport const npmPlanManual = options(\n\t`Audit the peer matrix and prepare a portable archive bundle; print matrix JSON.`,\n\ttype({\n\t\t...hiddenSchema,\n\t\t\"config?\": `string`,\n\t\t\"root?\": `string`,\n\t\t\"out?\": `string`,\n\t}),\n\t{\n\t\t...hidden,\n\t\troot,\n\t\tconfig: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: false,\n\t\t\tdescription: `TypeScript configuration containing npmMatrix.`,\n\t\t\texample: `--config breakage.config.ts`,\n\t\t\tcompletion: { fileSystem: `files` },\n\t\t},\n\t\tout: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: false,\n\t\t\tdescription: `Bundle directory (defaults to .breakage/npm-plan).`,\n\t\t\texample: `--out .breakage/peer-bundle`,\n\t\t\tcompletion: { fileSystem: `directories` },\n\t\t},\n\t},\n)\nexport const npmExecuteManual = options(\n\t`Execute one planned representative and write its receipt.`,\n\ttype({\n\t\t...hiddenSchema,\n\t\tplan: `string`,\n\t\treceipt: `string`,\n\t\t\"root?\": `string`,\n\t}),\n\t{\n\t\t...hidden,\n\t\troot,\n\t\tplan,\n\t\treceipt: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: true,\n\t\t\tdescription: `Output receipt filename.`,\n\t\t\texample: `--receipt .breakage/receipts/environment.json`,\n\t\t\tcompletion: { fileSystem: `files` },\n\t\t},\n\t},\n)\nexport const npmVerifyManual = options(\n\t`Verify the complete planned matrix against collected execution receipts.`,\n\ttype({\n\t\t...hiddenSchema,\n\t\tplan: `string`,\n\t\treceipts: `string`,\n\t\t\"root?\": `string`,\n\t}),\n\t{\n\t\t...hidden,\n\t\troot,\n\t\tplan,\n\t\treceipts: {\n\t\t\tschema: type(`string`),\n\t\t\trequired: true,\n\t\t\tdescription: `Glob selecting all collected JSON receipts, relative to root.`,\n\t\t\texample: `--receipts '.breakage/receipts/**/*.json'`,\n\t\t\tcompletion: { fileSystem: `files` },\n\t\t},\n\t},\n)\n\nexport async function runNpmMatrixCli(\n\taction: `plan` | `execute` | `verify`,\n\topts: {\n\t\troot?: string\n\t\tconfig?: string\n\t\tout?: string\n\t\tplan?: string\n\t\treceipt?: string\n\t\treceipts?: string\n\t},\n\tid?: string,\n): Promise<number> {\n\ttry {\n\t\tconst rootDirectory = path.resolve(opts.root ?? process.cwd())\n\t\tif (action === `plan`) {\n\t\t\tconst config = await loadConfig(\n\t\t\t\tpath.resolve(\n\t\t\t\t\trootDirectory,\n\t\t\t\t\topts.config ?? defaultConfig(rootDirectory),\n\t\t\t\t),\n\t\t\t)\n\t\t\tif (!config.npmMatrix)\n\t\t\t\tthrow new Error(`Configure npmMatrix.configs and npmMatrix.prepare.`)\n\t\t\tconst prepared = await npmPlan(config.npmMatrix, {\n\t\t\t\trootDirectory,\n\t\t\t\t...(opts.out ? { bundleDirectory: opts.out } : {}),\n\t\t\t})\n\t\t\tprocess.stdout.write(`${JSON.stringify(npmMatrix(prepared))}\\n`)\n\t\t\treturn 0\n\t\t}\n\t\tconst filename = path.resolve(rootDirectory, opts.plan!)\n\t\tconst value: unknown = JSON.parse(await readFile(filename, `utf8`))\n\t\tconst location = { rootDirectory, bundleDirectory: path.dirname(filename) }\n\t\tif (action === `execute`) {\n\t\t\tconst receipt = await npmExecute(value, id!, location)\n\t\t\tawait writeMatrixJson(path.resolve(rootDirectory, opts.receipt!), receipt)\n\t\t\tif (receipt.report) process.stdout.write(formatNpmReport(receipt.report))\n\t\t\tif (receipt.error) process.stderr.write(`${receipt.error}\\n`)\n\t\t\treturn receipt.exitCode\n\t\t}\n\t\tconst receipts: unknown[] = []\n\t\tfor await (const filename of glob(opts.receipts!, { cwd: rootDirectory }))\n\t\t\treceipts.push(\n\t\t\t\tJSON.parse(\n\t\t\t\t\tawait readFile(path.resolve(rootDirectory, filename), `utf8`),\n\t\t\t\t),\n\t\t\t)\n\t\tconst result = await npmVerify(value, receipts, location)\n\t\tif (result.errors.length)\n\t\t\tprocess.stderr.write(`${result.errors.join(`\\n`)}\\n`)\n\t\telse\n\t\t\tprocess.stdout.write(\n\t\t\t\t`Verified passing receipts for all ${result.environments} planned environments.\\n`,\n\t\t\t)\n\t\treturn result.exitCode\n\t} catch (error) {\n\t\tprocess.stderr.write(`npm matrix setup error: ${errorMessage(error)}\\n`)\n\t\treturn 2\n\t}\n}\n","#!/usr/bin/env node\n\nimport path from \"node:path\"\nimport { inspect } from \"node:util\"\n\nimport {\n\tcli,\n\tcompletionResponse,\n\tencapsulate,\n\thelp,\n\tlogWarnings,\n\tnoOptions,\n\toptional,\n\toptions,\n\tparseBooleanOption,\n\trequired,\n} from \"comline\"\nimport logger from \"takua\"\n\nimport {\n\tdefaultConfig,\n\tconfigPath,\n\tresolveConfig,\n\tconfigSchema,\n\tconfigFields,\n} from \"./config.ts\"\nimport { breakage, breakagePrelude } from \"./breakage.ts\"\nimport { errorMessage } from \"./task.ts\"\nimport { npmCheckManual, npmTestManual, runNpmCli } from \"./npm/cli.ts\"\nimport {\n\tnpmPlanManual,\n\tnpmExecuteManual,\n\tnpmVerifyManual,\n\trunNpmMatrixCli,\n} from \"./npm/matrix-cli.ts\"\n\n// Either command spelling can override the other spelling in a config file.\nconst commandOverrides = new Set<`test` | `testCommand`>()\n\nconst BREAKAGE_MANUAL = options(\n\t`Check for breaking changes in a package.`,\n\tconfigSchema,\n\t{\n\t\trelease: { configOnly: true },\n\t\tnpm: { configOnly: true },\n\t\tnpmMatrix: { configOnly: true },\n\t\tout: { configOnly: true },\n\t\ttagPattern: {\n\t\t\tschema: configFields.tagPattern,\n\t\t\taliases: [`tag-pattern`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `g`,\n\t\t\trequired: false,\n\t\t\tdescription: `RegExp which, if found matched to a git tag, will be considered a release tag for your library.`,\n\t\t\texample: `--tagPattern=\"my-library\"`,\n\t\t},\n\t\tbaselineFile: {\n\t\t\tschema: configFields.baselineFile,\n\t\t\taliases: [`baseline-file`],\n\t\t\tcompletion: { repeatable: false, fileSystem: `files` },\n\t\t\trequired: false,\n\t\t\tdescription: `Use the exact locally fetched commit from a prelude snapshot instead of discovering remote tags.`,\n\t\t\texample: `--baseline-file=.breakage/baseline.json`,\n\t\t},\n\t\ttestPattern: {\n\t\t\tschema: configFields.testPattern,\n\t\t\taliases: [`test-pattern`, `pattern`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `p`,\n\t\t\trequired: false,\n\t\t\tdescription: `The pattern to match test files that test the public API of the library.`,\n\t\t\texample: `--pattern=\"*__public.test.ts\"`,\n\t\t},\n\t\ttestCommand: {\n\t\t\tparse: (value) => {\n\t\t\t\tcommandOverrides.add(`testCommand`)\n\t\t\t\treturn value\n\t\t\t},\n\t\t\tschema: configFields.testCommand,\n\t\t\taliases: [`test-command`],\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `t`,\n\t\t\trequired: false,\n\t\t\tdescription: `Complete bash command that runs the tests for the library's public API.`,\n\t\t\texample: `--testCommand=\"npm run test\"`,\n\t\t},\n\t\ttest: {\n\t\t\tparse: (value) => {\n\t\t\t\tcommandOverrides.add(`test`)\n\t\t\t\treturn value\n\t\t\t},\n\t\t\tschema: configFields.test,\n\t\t\tcompletion: { repeatable: false },\n\t\t\trequired: false,\n\t\t\tdescription: `Shell command running the restored public contracts.`,\n\t\t\texample: `--test=\"npm run test:public\"`,\n\t\t},\n\t\tbaseDirname: {\n\t\t\tparse: (value) => path.resolve(value),\n\t\t\tschema: configFields.baseDirname,\n\t\t\taliases: [`base-dir`, `base-dirname`],\n\t\t\tcompletion: { repeatable: false, fileSystem: `directories` },\n\t\t\tflag: `d`,\n\t\t\trequired: false,\n\t\t\tdescription: `The base directory to run the command from.`,\n\t\t\texample: `--baseDirname=./packages/my-package`,\n\t\t},\n\t\tverbose: {\n\t\t\tschema: configFields.verbose,\n\t\t\tcompletion: { repeatable: false },\n\t\t\tflag: `v`,\n\t\t\trequired: false,\n\t\t\tdescription: `Prints out more information about the process.`,\n\t\t\texample: `--verbose`,\n\t\t\tparse: parseBooleanOption,\n\t\t},\n\t},\n)\n\nconst PRELUDE_MANUAL = options(\n\t`Resolve and fetch the release baseline for a cacheable compatibility check.`,\n\tconfigSchema,\n\t{\n\t\t...BREAKAGE_MANUAL.optionConfigs,\n\t\ttestPattern: {\n\t\t\t...BREAKAGE_MANUAL.optionConfigs.testPattern,\n\t\t\trequired: false,\n\t\t},\n\t\ttestCommand: {\n\t\t\t...BREAKAGE_MANUAL.optionConfigs.testCommand,\n\t\t\trequired: false,\n\t\t},\n\t\tout: {\n\t\t\tschema: configFields.out,\n\t\t\tcompletion: { repeatable: false, fileSystem: `files` },\n\t\t\trequired: false,\n\t\t\tdescription: `Gitignored snapshot path relative to the base directory (default: .breakage/baseline.json).`,\n\t\t\texample: `--out=.breakage/baseline.json`,\n\t\t},\n\t},\n)\n\nlet loadedConfigPath: string | undefined\nconst parse = cli(\n\t{\n\t\tcliName: `breakage`,\n\t\tdiscoverConfigPath: (segments: readonly string[]) => {\n\t\t\tif (segments[0] === `help` || segments[0] === `npm`) return undefined\n\t\t\tconst explicit = segments[0] === `prelude` ? segments[1] : segments[0]\n\t\t\tloadedConfigPath = configPath(\n\t\t\t\texplicit ?? defaultConfig(process.cwd()),\n\t\t\t\texplicit !== undefined,\n\t\t\t)\n\t\t\treturn loadedConfigPath\n\t\t},\n\t\troutes: optional({\n\t\t\thelp: null,\n\t\t\tnpm: optional({\n\t\t\t\thelp: null,\n\t\t\t\tcheck: null,\n\t\t\t\tplan: null,\n\t\t\t\texecute: required({ $id: null }),\n\t\t\t\tverify: null,\n\t\t\t\ttest: optional({ $peer: required({ $range: null }) }),\n\t\t\t}),\n\t\t\tprelude: optional({ $configPath: null }),\n\t\t\t$configPath: null,\n\t\t}),\n\t\trouteOptions: {\n\t\t\t\"\": BREAKAGE_MANUAL,\n\t\t\t$configPath: BREAKAGE_MANUAL,\n\t\t\thelp: noOptions(`Show usage.`),\n\t\t\tnpm: noOptions(`Show npm compatibility commands.`),\n\t\t\t\"npm/help\": noOptions(`Show npm compatibility commands.`),\n\t\t\t\"npm/check\": npmCheckManual,\n\t\t\t\"npm/plan\": npmPlanManual,\n\t\t\t\"npm/execute/$id\": npmExecuteManual,\n\t\t\t\"npm/verify\": npmVerifyManual,\n\t\t\t\"npm/test\": npmTestManual,\n\t\t\t\"npm/test/$peer/$range\": npmTestManual,\n\t\t\tprelude: PRELUDE_MANUAL,\n\t\t\t\"prelude/$configPath\": PRELUDE_MANUAL,\n\t\t},\n\t\tpositionalCompletions: {\n\t\t\t$configPath: { fileSystem: `files` },\n\t\t\t\"prelude/$configPath\": { fileSystem: `files` },\n\t\t},\n\t},\n\t{\n\t\tinfo: (message, ...data) => logger.info(`breakage`, message, data),\n\t\terror: (message, ...data) => logger.error(`breakage`, message, data),\n\t},\n)\n\nconst completion = await completionResponse(parse.definition, process.argv)\nif (completion !== undefined) {\n\tprocess.stdout.write(completion)\n} else {\n\ttry {\n\t\tconst { inputs, warnings } = await parse.async(process.argv)\n\t\tlogWarnings(warnings)\n\t\tif (\n\t\t\tprocess.argv\n\t\t\t\t.slice(2)\n\t\t\t\t.some((arg) =>\n\t\t\t\t\t/^(?:--certifyCommand|--certify-command|-c)(?:=|$)/.test(arg),\n\t\t\t\t)\n\t\t)\n\t\t\tthrow new Error(\n\t\t\t\t`certifyCommand was removed. Configure release.resolveDelta and release.policy instead.`,\n\t\t\t)\n\n\t\tswitch (inputs.case) {\n\t\t\tcase `npm`:\n\t\t\tcase `npm/help`:\n\t\t\tcase `help`:\n\t\t\t\tconsole.log(help(parse.definition))\n\t\t\t\tbreak\n\t\t\tcase `npm/check`:\n\t\t\t\tprocess.exitCode = await runNpmCli(`check`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/plan`:\n\t\t\t\tprocess.exitCode = await runNpmMatrixCli(`plan`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/execute/$id`:\n\t\t\t\tprocess.exitCode = await runNpmMatrixCli(\n\t\t\t\t\t`execute`,\n\t\t\t\t\tinputs.opts,\n\t\t\t\t\tinputs.params.id,\n\t\t\t\t)\n\t\t\t\tbreak\n\t\t\tcase `npm/verify`:\n\t\t\t\tprocess.exitCode = await runNpmMatrixCli(`verify`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/test`:\n\t\t\t\tprocess.exitCode = await runNpmCli(`test`, inputs.opts)\n\t\t\t\tbreak\n\t\t\tcase `npm/test/$peer/$range`:\n\t\t\t\tprocess.exitCode = await runNpmCli(`test`, inputs.opts, inputs.params)\n\t\t\t\tbreak\n\t\t\tcase `prelude`:\n\t\t\tcase `prelude/$configPath`: {\n\t\t\t\tconst config = resolveConfig(inputs.opts, loadedConfigPath)\n\t\t\t\tconst baseline = await breakagePrelude({\n\t\t\t\t\t...config,\n\t\t\t\t\tout: config.out ?? `.breakage/baseline.json`,\n\t\t\t\t})\n\t\t\t\tprocess.stdout.write(`Pinned ${baseline.ref} at ${baseline.commit}.\\n`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase ``:\n\t\t\tcase `$configPath`: {\n\t\t\t\tconst merged = resolveConfig(inputs.opts, loadedConfigPath)\n\t\t\t\tif (\n\t\t\t\t\tcommandOverrides.has(`testCommand`) &&\n\t\t\t\t\t!commandOverrides.has(`test`)\n\t\t\t\t)\n\t\t\t\t\tdelete merged.test\n\t\t\t\tif (\n\t\t\t\t\tcommandOverrides.has(`test`) &&\n\t\t\t\t\t!commandOverrides.has(`testCommand`)\n\t\t\t\t)\n\t\t\t\t\tdelete merged.testCommand\n\t\t\t\tif (!merged.testPattern)\n\t\t\t\t\tthrow new Error(`required arguments were not provided: testPattern.`)\n\t\t\t\tconst { returnValue } = await encapsulate(\n\t\t\t\t\t() =>\n\t\t\t\t\t\tbreakage({\n\t\t\t\t\t\t\t...merged,\n\t\t\t\t\t\t\ttestPattern: merged.testPattern!,\n\t\t\t\t\t\t}),\n\t\t\t\t\t{\n\t\t\t\t\t\tconsole: true,\n\t\t\t\t\t\tstdout: true,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\tif (`release` in returnValue && returnValue.release) {\n\t\t\t\t\tconst { previousVersion, version, delta, breaking } =\n\t\t\t\t\t\treturnValue.release\n\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t`Release: ${previousVersion} → ${version} (${delta}; ${breaking ? `breaking` : `compatible`}).\\n`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (`testResult` in returnValue && returnValue.breakingChangesFound) {\n\t\t\t\t\tprocess.stdout.write(returnValue.testResult)\n\t\t\t\t}\n\t\t\t\tif (`breakingChangesFound` in returnValue) {\n\t\t\t\t\tif (returnValue.breakingChangesFound) {\n\t\t\t\t\t\tif (returnValue.release?.breaking) {\n\t\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t\t`👷 Breaking changes are covered by the breaking release.`,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tprocess.exit(0)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t\t`❌ Breaking changes require a breaking release.`,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tprocess.exit(1)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprocess.stdout.write(`✅ No breaking changes were found.`)\n\t\t\t\t\t\tprocess.exit(0)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t`💥 Breakage failed to determine breaking changes.` +\n\t\t\t\t\t\t\t`\\n` +\n\t\t\t\t\t\t\tinspect(returnValue),\n\t\t\t\t\t)\n\t\t\t\t\tprocess.exit(2)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tprocess.stderr.write(`Breakage setup error: ${errorMessage(error)}\\n`)\n\t\tprocess.exitCode = 2\n\t}\n}\n"],"mappings":"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"}