repo-contract 0.2.0 → 0.3.2

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.2](https://github.com/MaverickCER/repo-contract/compare/repo-contract-v0.3.1...repo-contract-v0.3.2) (2026-09-04)
4
+
5
+
6
+ ### Features
7
+
8
+ * validate and transform check output with a Standard Schema ([d53cb17](https://github.com/MaverickCER/repo-contract/commit/d53cb17a9e3a3f939cd403226ab5256be0de79ac))
9
+ * validate and transform check output with a Standard Schema ([fbb7925](https://github.com/MaverickCER/repo-contract/commit/fbb79259f4a6cede1da64a0abd7e1f1541e1d505))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * address CodeRabbit findings and close mutation-testing gaps in Standard Schema support ([53baf87](https://github.com/MaverickCER/repo-contract/commit/53baf877d367fd17dbe1ec2f312ab9ed790e6ae6))
15
+ * **api-contract:** don't classify a required property on a brand-new container as breaking ([27ad5d5](https://github.com/MaverickCER/repo-contract/commit/27ad5d5c57811d90393b00f48ae8a8bbd413407b))
16
+ * **test:** harden isRuntimeAvailable against spawnSync throwing under load ([60c76b6](https://github.com/MaverickCER/repo-contract/commit/60c76b642dfd6187888f02d31639e68468e77b17))
17
+
18
+ ## [0.3.1](https://github.com/MaverickCER/repo-contract/compare/repo-contract-v0.3.0...repo-contract-v0.3.1) (2026-09-03)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * correct the release runbook that shipped types-less tarballs ([f56ea34](https://github.com/MaverickCER/repo-contract/commit/f56ea342606cfc92a09943ea5eb787936e7b7ba9))
24
+ * published tarball missing types; simplify CI matrix ([7ec8fd9](https://github.com/MaverickCER/repo-contract/commit/7ec8fd946bd584098255c5d2ab3f07b98b55ba1f))
25
+
26
+ ## [0.3.0](https://github.com/MaverickCER/repo-contract/compare/repo-contract-v0.2.1...repo-contract-v0.3.0) (2026-09-03)
27
+
28
+
29
+ ### ⚠ BREAKING CHANGES
30
+
31
+ * defineRepoContract/runRepoContract now require spawn and env on the config (e.g. spawn: child_process.spawn, env: process.env). See ADR 0011 and README's "Supplying spawn/env" section for migration.
32
+
33
+ ### Features
34
+
35
+ * contract engine, self-hosting checks and CI workflows ([97ae128](https://github.com/MaverickCER/repo-contract/commit/97ae128bd96f2c631057f1150068af58cc66b224))
36
+ * contract engine, self-hosting checks and CI workflows ([22b2a3b](https://github.com/MaverickCER/repo-contract/commit/22b2a3b03fe4e44ad7a01b82342d86583926416a))
37
+ * make process spawning and env access consumer-supplied capabilities ([640a961](https://github.com/MaverickCER/repo-contract/commit/640a961b65fd73511586c3b4f6274284bf5172a9))
38
+
39
+
40
+ ### Bug Fixes
41
+
42
+ * clear Socket supply-chain alerts (unminified dist, no prepare script) ([71c9230](https://github.com/MaverickCER/repo-contract/commit/71c92306fcf00e3858f0596c2d56f3272199339d))
43
+ * publish the dist bundle unminified ([266ae47](https://github.com/MaverickCER/repo-contract/commit/266ae47919753c55f10364713fe0c7c5876815b7))
44
+ * remove the prepare install script from the published package ([9153540](https://github.com/MaverickCER/repo-contract/commit/9153540e4f0f1a069e07c12ddfee8ba62827ce5b))
45
+
46
+ ## [0.2.1](https://github.com/MaverickCER/repo-contract/compare/repo-contract-v0.2.0...repo-contract-v0.2.1) (2026-09-03)
47
+
48
+
49
+ ### Documentation
50
+
51
+ * add Socket security badge to README
52
+
3
53
  ## [0.2.0](https://github.com/MaverickCER/repo-contract/compare/repo-contract-v0.1.1...repo-contract-v0.2.0) (2026-09-03)
4
54
 
5
55
 
package/README.md CHANGED
@@ -6,6 +6,7 @@
6
6
  [![Coverage](https://img.shields.io/badge/coverage-%E2%89%A585%25-brightgreen)](scripts/coverage-thresholds.mjs)
7
7
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)](tsconfig.json)
8
8
  [![Node](https://img.shields.io/node/v/repo-contract.svg)](package.json)
9
+ [![Socket Badge](https://badge.socket.dev/npm/package/repo-contract/latest)](https://badge.socket.dev/npm/package/repo-contract/latest)
9
10
 
10
11
  **Turn your repository's engineering standards into enforceable contracts.**
11
12
 
@@ -528,6 +529,50 @@ Provides trimmed text passthrough and always succeeds.
528
529
 
529
530
  The sibling mistake -- reading `result.output.value` when the format _was_ requested but the parse itself failed (`result.output.success === false`, so `result.output` has `error`, not `value`) -- similarly rejects with [`PolicyReadFailedParseValueError`](docs/api-report/repo-contract.api.md) instead of a generic `PolicyThrewError`. Check `result.output.success` before reading `.value` to handle a parse failure explicitly rather than hitting either error.
530
531
 
532
+ #### Validating parsed output with a schema
533
+
534
+ `output.schema` accepts any object implementing [Standard Schema](https://standardschema.dev) --
535
+ Zod, Valibot, ArkType, and others already do. repo-contract does not install or depend on any of
536
+ them; it hand-vendors the (pure-type, zero-runtime-code) `StandardSchemaV1` interface itself (see
537
+ [ADR 0012](specs/decisions/0012-hand-vendored-standard-schema-support-for-optional-output-validation.md)). Bring whichever schema
538
+ library your own repo already uses -- `npm install zod` (or `valibot`, or `arktype`) is your call,
539
+ not repo-contract's. The smallest possible example, using a hand-written object satisfying the
540
+ interface directly rather than any particular library:
541
+
542
+ ```ts
543
+ output: {
544
+ format: "json",
545
+ schema: {
546
+ "~standard": {
547
+ version: 1,
548
+ vendor: "example",
549
+ validate: (value) => {
550
+ const errorCount =
551
+ value !== null && typeof value === "object"
552
+ ? (value as { errorCount?: unknown }).errorCount
553
+ : undefined
554
+ return typeof errorCount === "number"
555
+ ? { value: { errorCount } }
556
+ : { issues: [{ message: "errorCount must be a number", path: ["errorCount"] }] }
557
+ },
558
+ },
559
+ },
560
+ }
561
+ ```
562
+
563
+ A successful validation _replaces_ `result.output.value` with the schema's own (possibly
564
+ transformed or coerced) output -- one of the most useful aspects of Standard Schema, not just a
565
+ boolean check: a schema can normalize, default, or reshape its input, and the policy receives that
566
+ result, not the raw parsed value. A failing validation becomes a normal `ParsedOutputFailure` --
567
+ indistinguishable in shape from a malformed-JSON parse failure, joining every issue's own path and
568
+ message into `result.output.error` (e.g. `Schema validation failed: errorCount: errorCount must be
569
+ a number`). `result.output.value`'s declared TypeScript type stays `unknown` regardless -- narrow
570
+ or cast it yourself, same as without a schema.
571
+
572
+ `schema["~standard"].validate()` itself throwing or rejecting (rather than returning a `Result`) is
573
+ different from a failed validation -- it means the schema is broken, not the check's output, so it
574
+ rejects `runRepoContract()` with `StandardSchemaValidateThrewError` instead of becoming evidence.
575
+
531
576
  ### `dependsOn`
532
577
 
533
578
  By default, every check runs independently and in parallel.
@@ -1000,6 +1045,8 @@ A **policy throwing** is different. A synchronous throw or rejected promise from
1000
1045
 
1001
1046
  Two specific mistakes get their own error instead of a plain `PolicyThrewError`, both naming the check: reading `result.output.value` (or `.success`/`.error`/`.format`) on a check that never configured `output` throws `PolicyReadUnrequestedOutputError`, telling you to add `output: { format: "json" }` (or `"yaml"`/`"text"`); reading `result.output.value` on a check whose requested parse actually failed throws `PolicyReadFailedParseValueError`, telling you to check `result.output.success` first -- see [`output`](#output).
1002
1047
 
1048
+ A **schema throwing** (`output.schema["~standard"].validate()` itself throwing or rejecting, rather than returning a `Result` -- see [Validating parsed output with a schema](#validating-parsed-output-with-a-schema)) is treated the same as a throwing policy: `StandardSchemaValidateThrewError`, or an `AggregateError` when multiple checks' schemas throw in the same run. A schema _returning_ failure `issues`, by contrast, is not an error at all -- it becomes an ordinary parser-error-shaped `result.output`, exactly like the **Parser errors** case above.
1049
+
1003
1050
  ## Status and versioning
1004
1051
 
1005
1052
  repo-contract is pre-1.0.
@@ -1 +1 @@
1
- {"version":3,"file":"validate-config.d.ts","sourceRoot":"","sources":["../../../src/config/validate-config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAgB,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAKnE;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAuE3E;AAqSD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,GACxD,IAAI,CAoBN"}
1
+ {"version":3,"file":"validate-config.d.ts","sourceRoot":"","sources":["../../../src/config/validate-config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAgB,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAKnE;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAuE3E;AA2VD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC,GACxD,IAAI,CAoBN"}
@@ -74,6 +74,23 @@ export declare class ParserDependencyMissingError extends RepoContractError {
74
74
  constructor(checkId: string, format: OutputFormatForError, cause: unknown);
75
75
  }
76
76
  type OutputFormatForError = "yaml";
77
+ /**
78
+ * A check's `output.schema["~standard"].validate()` threw synchronously, or returned a `Promise`
79
+ * that rejected, instead of returning a `Result`. This is a bug in the consumer-supplied schema
80
+ * object, not malformed check output -- the same distinction `PolicyThrewError` below draws for a
81
+ * throwing policy: a schema *returning* failure `issues` becomes an ordinary
82
+ * `ParsedOutputFailure` (reported as data, exactly like a malformed-JSON/YAML parse failure), but
83
+ * a schema *throwing* means the validator itself is broken, so it propagates as a rejected
84
+ * `runRepoContract()` promise instead. The original thrown/rejected value is preserved verbatim
85
+ * via the native `Error` `cause` chain.
86
+ */
87
+ export declare class StandardSchemaValidateThrewError extends RepoContractError {
88
+ /** Always `"REPO_CONTRACT_STANDARD_SCHEMA_VALIDATE_THREW"`. */
89
+ readonly code = "REPO_CONTRACT_STANDARD_SCHEMA_VALIDATE_THREW";
90
+ /** The id of the check whose `output.schema` threw during validation. */
91
+ readonly checkId: string;
92
+ constructor(checkId: string, cause: unknown);
93
+ }
77
94
  /**
78
95
  * A check's `policy` function threw synchronously, or returned a `Promise`
79
96
  * that later rejected. Both failure modes are wrapped identically. The
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,8BAAsB,iBAAkB,SAAQ,KAAK;IACnD,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAC/B;AAED,+aAA+a;AAC/a,qBAAa,8BAA+B,SAAQ,iBAAiB;IACnE,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,kCAAiC;gBAElC,MAAM,EAAE,MAAM;CAI3B;AAED,sPAAsP;AACtP,qBAAa,uBAAwB,SAAQ,iBAAiB;IAC5D,qDAAqD;IACrD,QAAQ,CAAC,IAAI,wCAAuC;IACpD,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,iBAAiB;IACxD,iDAAiD;IACjD,QAAQ,CAAC,IAAI,oCAAmC;IAChD,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM;CAO5B;AAED;;;;;;GAMG;AACH,qBAAa,4BAA6B,SAAQ,iBAAiB;IACjE,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,6CAA4C;IACzD,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,oEAAoE;IACpE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;gBAEjB,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAUlD;AAED,kPAAkP;AAClP,qBAAa,4BAA6B,SAAQ,iBAAiB;IACjE,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,6CAA4C;IACzD,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAA;gBAEzB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,KAAK,EAAE,OAAO;CAU1E;AAMD,KAAK,oBAAoB,GAAG,MAAM,CAAA;AAElC;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAiB,SAAQ,iBAAiB;IACrD,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,gCAA+B;IAC5C,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAK5C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,gCAAiC,SAAQ,iBAAiB;IACrE,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,kDAAiD;IAC9D,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAY9D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,+BAAgC,SAAQ,iBAAiB;IACpE,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,kDAAiD;IAC9D,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAU9D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,8BAAsB,iBAAkB,SAAQ,KAAK;IACnD,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAC/B;AAED,+aAA+a;AAC/a,qBAAa,8BAA+B,SAAQ,iBAAiB;IACnE,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,kCAAiC;gBAElC,MAAM,EAAE,MAAM;CAI3B;AAED,sPAAsP;AACtP,qBAAa,uBAAwB,SAAQ,iBAAiB;IAC5D,qDAAqD;IACrD,QAAQ,CAAC,IAAI,wCAAuC;IACpD,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,iBAAiB;IACxD,iDAAiD;IACjD,QAAQ,CAAC,IAAI,oCAAmC;IAChD,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM;CAO5B;AAED;;;;;;GAMG;AACH,qBAAa,4BAA6B,SAAQ,iBAAiB;IACjE,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,6CAA4C;IACzD,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,oEAAoE;IACpE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;gBAEjB,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAUlD;AAED,kPAAkP;AAClP,qBAAa,4BAA6B,SAAQ,iBAAiB;IACjE,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,6CAA4C;IACzD,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAA;gBAEzB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,KAAK,EAAE,OAAO;CAU1E;AAMD,KAAK,oBAAoB,GAAG,MAAM,CAAA;AAElC;;;;;;;;;GASG;AACH,qBAAa,gCAAiC,SAAQ,iBAAiB;IACrE,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,kDAAiD;IAC9D,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAQ5C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAiB,SAAQ,iBAAiB;IACrD,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,gCAA+B;IAC5C,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAK5C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,gCAAiC,SAAQ,iBAAiB;IACrE,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,kDAAiD;IAC9D,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAY9D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,+BAAgC,SAAQ,iBAAiB;IACpE,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,kDAAiD;IAC9D,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAU9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"build-evidence.d.ts","sourceRoot":"","sources":["../../../src/evidence/build-evidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAGrE,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3E,iQAAiQ;AACjQ,MAAM,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,aAAa,CAAC,CAAA;AAIhF,UAAU,aAAa;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAC9C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,SAAS,EAAE,IAAI,EACf,WAAW,EAAE,IAAI,GAChB,OAAO,CAAC,aAAa,CAAC,CAwDxB"}
1
+ {"version":3,"file":"build-evidence.d.ts","sourceRoot":"","sources":["../../../src/evidence/build-evidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAGrE,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3E,iQAAiQ;AACjQ,MAAM,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,EAAE,eAAe,EAAE,aAAa,CAAC,CAAA;AAIhF,UAAU,aAAa;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAC9C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,SAAS,EAAE,IAAI,EACf,WAAW,EAAE,IAAI,GAChB,OAAO,CAAC,aAAa,CAAC,CAgExB"}
@@ -8,6 +8,7 @@
8
8
  */
9
9
  export { defineRepoContract } from "./config/define-repo-contract.js";
10
10
  export { runRepoContract } from "./run-repo-contract.js";
11
- export { DependencyDeclaredLaterError, InvalidCheckConfigError, InvalidRepoContractConfigError, ParserDependencyMissingError, PolicyReadFailedParseValueError, PolicyReadUnrequestedOutputError, PolicyThrewError, RepoContractError, UnknownCheckIdError, } from "./errors.js";
11
+ export { DependencyDeclaredLaterError, InvalidCheckConfigError, InvalidRepoContractConfigError, ParserDependencyMissingError, PolicyReadFailedParseValueError, PolicyReadUnrequestedOutputError, PolicyThrewError, RepoContractError, StandardSchemaValidateThrewError, UnknownCheckIdError, } from "./errors.js";
12
+ export type { StandardSchemaV1 } from "./standard-schema/types.js";
12
13
  export type { CheckDefinition, CheckDefinitionConfig, CheckEvidence, CheckSchema, CheckStatus, Evidence, OutputFormat, ParsedOutput, ParsedOutputFailure, ParsedOutputSuccess, Policy, PolicyContext, PolicyOutcome, PolicyResult, RepoContractConfig, RunRepoContractOptions, Spawner, SyncSpawner, ValidatedCheckSchema, Verdict, } from "./types.js";
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,4BAA4B,EAC5B,+BAA+B,EAC/B,gCAAgC,EAChC,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,aAAa,CAAA;AAEpB,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,WAAW,EACX,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,EACN,aAAa,EACb,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,OAAO,EACP,WAAW,EACX,oBAAoB,EACpB,OAAO,GACR,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,4BAA4B,EAC5B,+BAA+B,EAC/B,gCAAgC,EAChC,gBAAgB,EAChB,iBAAiB,EACjB,gCAAgC,EAChC,mBAAmB,GACpB,MAAM,aAAa,CAAA;AAEpB,YAAY,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAElE,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,aAAa,EACb,WAAW,EACX,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,EACN,aAAa,EACb,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,OAAO,EACP,WAAW,EACX,oBAAoB,EACpB,OAAO,GACR,MAAM,YAAY,CAAA"}
@@ -0,0 +1,11 @@
1
+ import type { StandardSchemaV1 } from "../standard-schema/types.js";
2
+ /**
3
+ * Renders a failed `output.schema` validation's issues as a single, human-readable string for
4
+ * `ParsedOutputFailure.error` -- e.g. `Schema validation failed: foo.bar: Expected string;
5
+ * items[2].name: Required`. Kept as its own small module, independent of `parseOutput`, so its
6
+ * path-rendering logic (the only non-trivial part) can be unit-tested directly.
7
+ * @param issues - the failed `StandardSchemaV1.Result`'s `issues`.
8
+ * @returns the formatted error string.
9
+ */
10
+ export declare function formatSchemaIssues(issues: readonly StandardSchemaV1.Issue[]): string;
11
+ //# sourceMappingURL=format-schema-issues.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-schema-issues.d.ts","sourceRoot":"","sources":["../../../src/parsing/format-schema-issues.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAEnE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,gBAAgB,CAAC,KAAK,EAAE,GAAG,MAAM,CAEpF"}
@@ -1,10 +1,25 @@
1
+ import type { StandardSchemaV1 } from "../standard-schema/types.js";
1
2
  import type { OutputFormat, ParsedOutput } from "../types.js";
2
3
  /**
3
- * Dispatches to the parser for `format`. Never throws for a malformed-output parse failure -- see each parser's own documentation. May throw `ParserDependencyMissingError` for `format: "yaml"` if the optional `yaml` peer dependency is unavailable.
4
+ * Dispatches to the parser for `format`, then -- only on a successful parse, and only if `schema`
5
+ * is supplied -- runs `schema["~standard"].validate()` against the parsed value
6
+ * (https://standardschema.dev). `parse-json.ts`/`parse-yaml.ts`/`parse-text.ts` stay entirely
7
+ * unaware of `schema`; this is the sole orchestration point. `validate()` may return its `Result`
8
+ * synchronously or as a `Promise` -- `await`ing either uniformly is a no-op for the synchronous
9
+ * case, so this doesn't need its own reason to be async on top of the one this function already
10
+ * has (the dynamic `import("yaml")` for `format: "yaml"`). A successful `Result` (`issues ===
11
+ * undefined`) *replaces* `value` with the schema's own (possibly transformed) output; a failing
12
+ * `Result` becomes a `ParsedOutputFailure` whose `error` is built by `formatSchemaIssues`.
13
+ * `schema.validate()` itself throwing or rejecting is a bug in the consumer-supplied schema, not
14
+ * malformed output -- it throws `StandardSchemaValidateThrewError` rather than becoming a
15
+ * `ParsedOutputFailure`. Never throws for a malformed-output parse failure -- see each parser's
16
+ * own documentation. May throw `ParserDependencyMissingError` for `format: "yaml"` if the
17
+ * optional `yaml` peer dependency is unavailable.
4
18
  * @param format - which parser to dispatch to.
5
19
  * @param stdout - the check's raw stdout to parse.
6
- * @param checkId - identifies which check's output is being parsed, used in the `ParserDependencyMissingError` thrown for a missing `yaml` dependency.
7
- * @returns the parsed output produced by the selected parser.
20
+ * @param checkId - identifies which check's output is being parsed, used in a thrown `ParserDependencyMissingError`/`StandardSchemaValidateThrewError`.
21
+ * @param schema - an optional Standard Schema-compliant validator to run against a successful parse's value.
22
+ * @returns the parsed (and, if `schema` was supplied and validation succeeded, schema-transformed) output.
8
23
  */
9
- export declare function parseOutput(format: OutputFormat, stdout: string, checkId: string): Promise<ParsedOutput<unknown>>;
24
+ export declare function parseOutput(format: OutputFormat, stdout: string, checkId: string, schema?: StandardSchemaV1): Promise<ParsedOutput<unknown>>;
10
25
  //# sourceMappingURL=parse-output.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-output.d.ts","sourceRoot":"","sources":["../../../src/parsing/parse-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK7D;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAShC"}
1
+ {"version":3,"file":"parse-output.d.ts","sourceRoot":"","sources":["../../../src/parsing/parse-output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAM7D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAkBhC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Hand-vendored from `@standard-schema/spec@1.1.0` (https://standardschema.dev), pinned
3
+ * 2026-09-04 -- see specs/decisions/0012-hand-vendored-standard-schema-support-for-optional-output-validation.md for why this is
4
+ * vendored rather than an installed dependency, and for the version-pin/re-diff process. Pure type
5
+ * declarations, zero runtime code -- assigning any real Zod/Valibot/ArkType (etc.) schema to this
6
+ * type costs nothing at runtime. Only `StandardSchemaV1` (validation) is vendored here -- the
7
+ * separate, optional `StandardJSONSchemaV1` (JSON Schema conversion) extension
8
+ * (https://standardschema.dev/json-schema) is out of scope; see the ADR.
9
+ *
10
+ * Upstream's `StandardSchemaV1.Props` actually extends a shared `StandardTypedV1.Props` base
11
+ * (`version`/`vendor`/`types`); this vendored copy inlines those fields directly into one flat
12
+ * interface, since repo-contract has no use for the shared base on its own -- structurally
13
+ * identical for any real schema object assigned to it. Re-diff against
14
+ * `@standard-schema/spec`'s published `dist/index.d.ts` if this file is ever touched.
15
+ */
16
+ export interface StandardSchemaV1<Input = unknown, Output = Input> {
17
+ /** The Standard Schema properties. */
18
+ readonly "~standard": StandardSchemaV1.Props<Input, Output>;
19
+ }
20
+ /** Namespaced members of {@link StandardSchemaV1}: `Props`, `Result`, `SuccessResult`, `FailureResult`, `Issue`, `PathSegment`, `Types`, `InferInput`, `InferOutput`. */
21
+ export declare namespace StandardSchemaV1 {
22
+ /** The Standard Schema properties interface. */
23
+ interface Props<Input = unknown, Output = Input> {
24
+ /** The version number of the standard. */
25
+ readonly version: 1;
26
+ /** The vendor name of the schema library. */
27
+ readonly vendor: string;
28
+ /** Validates unknown input values. */
29
+ readonly validate: (value: unknown, options?: Options) => Result<Output> | Promise<Result<Output>>;
30
+ /** Inferred types associated with the schema. */
31
+ readonly types?: Types<Input, Output> | undefined;
32
+ }
33
+ /** Options passable to `validate`. */
34
+ interface Options {
35
+ /** Explicit support for additional vendor-specific parameters, if needed. */
36
+ readonly libraryOptions?: Record<string, unknown> | undefined;
37
+ }
38
+ /** The result interface of the validate function. */
39
+ type Result<Output> = SuccessResult<Output> | FailureResult;
40
+ /** The result interface if validation succeeds. */
41
+ interface SuccessResult<Output> {
42
+ /** The typed output value. */
43
+ readonly value: Output;
44
+ /** A falsy value for `issues` indicates success. */
45
+ readonly issues?: undefined;
46
+ }
47
+ /** The result interface if validation fails. */
48
+ interface FailureResult {
49
+ /** The issues of failed validation. */
50
+ readonly issues: readonly Issue[];
51
+ }
52
+ /** The issue interface of the failure output. */
53
+ interface Issue {
54
+ /** The error message of the issue. */
55
+ readonly message: string;
56
+ /** The path of the issue, if any. */
57
+ readonly path?: readonly (PropertyKey | PathSegment)[] | undefined;
58
+ }
59
+ /** The path segment interface of the issue. */
60
+ interface PathSegment {
61
+ /** The key representing a path segment. */
62
+ readonly key: PropertyKey;
63
+ }
64
+ /** The Standard Schema types interface. */
65
+ interface Types<Input = unknown, Output = Input> {
66
+ /** The input type of the schema. */
67
+ readonly input: Input;
68
+ /** The output type of the schema. */
69
+ readonly output: Output;
70
+ }
71
+ /** Infers the input type of a Standard Schema. */
72
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
73
+ /** Infers the output type of a Standard Schema. */
74
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
75
+ }
76
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/standard-schema/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;IAC/D,sCAAsC;IACtC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;CAC5D;AAED,yKAAyK;AAEzK,MAAM,CAAC,OAAO,WAAW,gBAAgB,CAAC;IACxC,gDAAgD;IAChD,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,0CAA0C;QAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;QACnB,6CAA6C;QAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,sCAAsC;QACtC,QAAQ,CAAC,QAAQ,EAAE,CACjB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,OAAO,KACd,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;QAC7C,iDAAiD;QACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;KAClD;IAED,sCAAsC;IACtC,UAAiB,OAAO;QACtB,6EAA6E;QAC7E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;KAC9D;IAED,qDAAqD;IACrD,KAAY,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,aAAa,CAAA;IAElE,mDAAmD;IACnD,UAAiB,aAAa,CAAC,MAAM;QACnC,8BAA8B;QAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,oDAAoD;QACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;KAC5B;IAED,gDAAgD;IAChD,UAAiB,aAAa;QAC5B,uCAAuC;QACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAA;KAClC;IAED,iDAAiD;IACjD,UAAiB,KAAK;QACpB,sCAAsC;QACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;QACxB,qCAAqC;QACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,WAAW,CAAC,EAAE,GAAG,SAAS,CAAA;KACnE;IAED,+CAA+C;IAC/C,UAAiB,WAAW;QAC1B,2CAA2C;QAC3C,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAA;KAC1B;IAED,2CAA2C;IAC3C,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,oCAAoC;QACpC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;QACrB,qCAAqC;QACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KACxB;IAED,kDAAkD;IAClD,KAAY,UAAU,CAAC,MAAM,SAAS,gBAAgB,IAAI,WAAW,CACnE,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAC7B,CAAC,OAAO,CAAC,CAAA;IAEV,mDAAmD;IACnD,KAAY,WAAW,CAAC,MAAM,SAAS,gBAAgB,IAAI,WAAW,CACpE,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAC7B,CAAC,QAAQ,CAAC,CAAA;CACZ"}
@@ -5,6 +5,7 @@
5
5
  * `runRepoContract` returns both together.
6
6
  */
7
7
  import type { ChildProcess, SpawnOptions, SpawnSyncOptions, SpawnSyncReturns } from "node:child_process";
8
+ import type { StandardSchemaV1 } from "./standard-schema/types.js";
8
9
  /** Output interpretation a check can explicitly request. No format requested means no parsing -- the consumer gets raw stdout/stderr only. */
9
10
  export type OutputFormat = "json" | "yaml" | "text";
10
11
  /**
@@ -53,16 +54,21 @@ export type ParsedOutput<T> = ParsedOutputSuccess<T> | ParsedOutputFailure;
53
54
  * `undefined` -- a policy narrows with `ctx.result.output?.success` (or an
54
55
  * `if (ctx.result.output) { ... }` guard) before reading `.value`/`.error`.
55
56
  *
56
- * `output.value` is typed `unknown` for every format, including `"text"`
57
- * (even though `parseText` always produces a `string` at runtime) --
58
- * neither repo-contract nor TypeScript's generic inference can reliably
59
- * carry a specific check's own literal `output.format` through to that
60
- * same check's `policy` parameter once several checks with heterogeneous
61
- * formats live together in one `checks` record (a real TypeScript
62
- * inference limitation hit and confirmed during implementation, not a
63
- * hypothetical -- see specs/decisions/ for the isolated repro). A policy
64
- * author narrows or casts `.value` themselves, exactly as they already must
65
- * for `"json"`/`"yaml"` where no schema knowledge exists either way.
57
+ * `output.value` is the value produced by the configured `format` parser, optionally validated
58
+ * and (if a schema transforms/coerces it) replaced by `output.schema` (see
59
+ * `CheckDefinitionConfig.output.schema`) -- so it is not necessarily the raw parser result once a
60
+ * check's config supplies a schema. It is typed `unknown` for every format regardless, including
61
+ * `"text"` (even though `parseText` always produces a `string` at runtime) and regardless of
62
+ * whether a schema was supplied -- neither repo-contract nor TypeScript's generic inference can
63
+ * reliably carry a specific check's own literal `output.format` (or a specific `schema`'s own
64
+ * inferred output type) through to that same check's `policy` parameter once several checks with
65
+ * heterogeneous formats live together in one `checks` record (a real TypeScript inference
66
+ * limitation hit and confirmed during implementation, not a hypothetical -- see specs/decisions/
67
+ * for the isolated repro). This is a deliberate, acknowledged tradeoff, not a gap this package
68
+ * is attempting to close: a schema still gives its own author real compile-time input/output
69
+ * typing via `StandardSchemaV1<Input, Output>` for their own code, just not threaded through this
70
+ * shared `CheckEvidence` shape. A policy author narrows or casts `.value` themselves, exactly as
71
+ * they already must for `"json"`/`"yaml"` with no schema supplied.
66
72
  */
67
73
  export interface CheckEvidence {
68
74
  /** The executable that was actually spawned (after tokenization, if `run` was a string). */
@@ -89,7 +95,12 @@ export interface CheckEvidence {
89
95
  readonly spawnError?: string;
90
96
  /** Populated only for `status === "spawn_error"` -- the underlying Node `ErrnoException`'s structured `.code` (e.g. `"ENOENT"`, `"EACCES"`), when Node provides one. Never populated for any other status. Distinguishes "the executable does not exist" from other spawn failures (permission denied, invalid executable format, etc.) without parsing `spawnError`'s free-text message. */
91
97
  readonly spawnErrorCode?: string;
92
- /** The parsed interpretation of `stdout`, present only if this check's config requested a `format`. */
98
+ /**
99
+ * The parsed interpretation of `stdout`, present only if this check's config requested a
100
+ * `format`. If that config also supplied `output.schema`, a successful parse is additionally
101
+ * validated (and possibly transformed) by that schema before landing here -- see this
102
+ * interface's own doc comment above and `CheckDefinitionConfig.output.schema`.
103
+ */
93
104
  readonly output?: ParsedOutput<unknown>;
94
105
  }
95
106
  /**
@@ -221,6 +232,28 @@ export interface CheckDefinitionConfig {
221
232
  /** Request that stdout be parsed as this format. Omit for no parsing -- the consumer gets raw stdout/stderr only. */
222
233
  readonly output?: {
223
234
  readonly format: OutputFormat;
235
+ /**
236
+ * An optional Standard Schema-compliant validator (Zod, Valibot, ArkType, or any other
237
+ * implementation of https://standardschema.dev), run once the requested `format` parse
238
+ * itself succeeds. repo-contract never imports a schema library itself --
239
+ * `StandardSchemaV1` is hand-vendored (see `src/standard-schema/types.ts`) purely as a
240
+ * type-level contract, so accepting any consumer's own schema object costs zero new
241
+ * runtime or dev dependencies (see
242
+ * specs/decisions/0012-hand-vendored-standard-schema-support-for-optional-output-validation.md). A successful
243
+ * `~standard.validate()` result *replaces* the parsed value on `CheckEvidence.output.value`
244
+ * (letting a schema transform, not just check, its input); a failing result becomes an
245
+ * ordinary `ParsedOutputFailure`, indistinguishable in shape from a malformed-JSON/YAML
246
+ * parse failure -- both are "this check's output isn't what was expected," reported as
247
+ * data, never a throw (see `parseOutput`). `validate()` itself throwing or rejecting is a
248
+ * different case -- a bug in the supplied schema, not malformed output -- and surfaces as
249
+ * `StandardSchemaValidateThrewError` instead (see that error's own doc comment). Like every
250
+ * other format's `value`, `schema`'s inferred output type is *not* threaded to
251
+ * `CheckEvidence.output.value`'s declared type -- it stays `unknown`, for the same
252
+ * heterogeneous-checks-in-one-record TypeScript inference limitation already documented on
253
+ * `CheckEvidence` above; a policy still narrows or casts `.value` itself, now
254
+ * shaped/transformed by `schema` at runtime even though the type alone doesn't say so.
255
+ */
256
+ readonly schema?: StandardSchemaV1;
224
257
  };
225
258
  /**
226
259
  * A full scheduling barrier at this check's own position in the `checks` object: it does not
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,oBAAoB,CAAA;AAE3B,8IAA8I;AAC9I,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAEnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,WAAW,GACrB,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,iBAAiB,GAAG,aAAa,GAAG,SAAS,CAAA;AAExF,uDAAuD;AACvD,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,qBAAqB;IACrB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;IACtB,wBAAwB;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,sBAAsB;IACtB,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAA;IACvB,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,oIAAoI;AACpI,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAA;AAE1E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,aAAa;IAC5B,4FAA4F;IAC5F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,mGAAmG;IACnG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;IACtC,6JAA6J;IAC7J,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4JAA4J;IAC5J,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,0JAA0J;IAC1J,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,6XAA6X;IAC7X,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,uGAAuG;IACvG,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;CACxC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ,CAAC,OAAO,SAAS,WAAW,GAAG,WAAW;IACjE,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,OAAO,GAAG,aAAa;KAAE,CAAA;CAClE;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa,CAAC,OAAO,SAAS,WAAW,GAAG,WAAW;IACtE,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IACpC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;CAC/D;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAEpD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;IAC/B,+FAA+F;IAC/F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,MAAM,CAAC,OAAO,SAAS,WAAW,GAAG,WAAW,IAAI,CAC9D,GAAG,EAAE,aAAa,CAAC,OAAO,CAAC,KACxB,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;AAEzC,8JAA8J;AAC9J,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;IACxB,0FAA0F;IAC1F,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,0JAA0J;IAC1J,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,mSAAmS;IACnS,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;IAC7B,2IAA2I;IAC3I,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,qHAAqH;IACrH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;KAAE,CAAA;IACnD;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,0JAA0J;AAC1J,MAAM,WAAW,eAAgB,SAAQ,qBAAqB;IAC5D;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACvC;AAED,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;IACpC,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,qBAAqB,GACvD,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG;QACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,CAAA;KAC/D,GACD,KAAK;CACV,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,OAAO,GAAG,CACpB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,YAAY,KAClB,YAAY,CAAA;AAEjB;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,gBAAgB,KACtB,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC,CAAA;AAEtC,gFAAgF;AAChF,MAAM,WAAW,kBAAkB,CAAC,OAAO,SAAS,WAAW,GAAG,WAAW;IAC3E,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,6HAA6H;IAC7H,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB;;;;;;;;;OASG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,CAAA;CACvC;AAED,uDAAuD;AACvD,MAAM,WAAW,sBAAsB;IACrC,oOAAoO;IACpO,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;IAC7B,yIAAyI;IACzI,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,OAAO,CAAC,OAAO,SAAS,WAAW,GAAG,WAAW;IAChE,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,OAAO,GAAG,YAAY;KAAE,CAAA;CACjE"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -96,6 +96,20 @@ var ParserDependencyMissingError = class extends RepoContractError {
96
96
  this.format = format;
97
97
  }
98
98
  };
99
+ var StandardSchemaValidateThrewError = class extends RepoContractError {
100
+ /** Always `"REPO_CONTRACT_STANDARD_SCHEMA_VALIDATE_THREW"`. */
101
+ code = "REPO_CONTRACT_STANDARD_SCHEMA_VALIDATE_THREW";
102
+ /** The id of the check whose `output.schema` threw during validation. */
103
+ checkId;
104
+ constructor(checkId, cause) {
105
+ super(
106
+ `Check "${checkId}"'s output.schema["~standard"].validate() threw instead of returning a Result`,
107
+ { cause }
108
+ );
109
+ this.name = "StandardSchemaValidateThrewError";
110
+ this.checkId = checkId;
111
+ }
112
+ };
99
113
  var PolicyThrewError = class extends RepoContractError {
100
114
  /** Always `"REPO_CONTRACT_POLICY_THREW"`. */
101
115
  code = "REPO_CONTRACT_POLICY_THREW";
@@ -380,13 +394,46 @@ function validateOutput(checkId, output) {
380
394
  if (output === null || typeof output !== "object") {
381
395
  throw new InvalidCheckConfigError(checkId, "output must be an object when provided.");
382
396
  }
383
- const { format } = output;
397
+ const { format, schema } = output;
384
398
  if (typeof format !== "string" || !OUTPUT_FORMATS.includes(format)) {
385
399
  throw new InvalidCheckConfigError(
386
400
  checkId,
387
401
  `output.format must be one of ${OUTPUT_FORMATS.map((f) => `"${f}"`).join(", ")}.`
388
402
  );
389
403
  }
404
+ validateOutputSchema(checkId, schema);
405
+ }
406
+ function validateOutputSchema(checkId, schema) {
407
+ if (schema === void 0) return;
408
+ if (schema === null || typeof schema !== "object" && typeof schema !== "function") {
409
+ throw new InvalidCheckConfigError(
410
+ checkId,
411
+ "output.schema must be a Standard Schema-compliant object or function when provided (see https://standardschema.dev)."
412
+ );
413
+ }
414
+ const standard = schema["~standard"];
415
+ if (standard === null || typeof standard !== "object") {
416
+ throw new InvalidCheckConfigError(
417
+ checkId,
418
+ 'output.schema must have a "~standard" property (see https://standardschema.dev).'
419
+ );
420
+ }
421
+ const { version, vendor, validate } = standard;
422
+ if (version !== 1) {
423
+ throw new InvalidCheckConfigError(checkId, 'output.schema["~standard"].version must be 1.');
424
+ }
425
+ if (typeof vendor !== "string") {
426
+ throw new InvalidCheckConfigError(
427
+ checkId,
428
+ 'output.schema["~standard"].vendor must be a string.'
429
+ );
430
+ }
431
+ if (typeof validate !== "function") {
432
+ throw new InvalidCheckConfigError(
433
+ checkId,
434
+ 'output.schema["~standard"].validate must be a function.'
435
+ );
436
+ }
390
437
  }
391
438
  function validatePolicy(checkId, policy) {
392
439
  if (typeof policy !== "function") {
@@ -427,6 +474,28 @@ function validateDependencyGraph(checks) {
427
474
  }
428
475
  }
429
476
 
477
+ // src/parsing/format-schema-issues.ts
478
+ function formatSchemaIssues(issues) {
479
+ return `Schema validation failed: ${issues.map(formatIssue).join("; ")}`;
480
+ }
481
+ function formatIssue(issue) {
482
+ const path = formatPath(issue.path);
483
+ return path === "" ? issue.message : `${path}: ${issue.message}`;
484
+ }
485
+ function formatPath(path) {
486
+ if (path === void 0 || path.length === 0) return "";
487
+ return path.map(
488
+ (segment) => (
489
+ // eslint-disable-next-line secure-coding/no-improper-type-validation -- `segment` is declared `PropertyKey | StandardSchemaV1.PathSegment` (never `null` or an array), so `typeof segment === "object"` can only match the `PathSegment` object form here; the null/array-safe rewrite this rule suggests is flagged as an unreachable condition by @typescript-eslint/no-unnecessary-condition given that exact type, so satisfying both rules at once is impossible -- the type itself is the guarantee this check would otherwise add at runtime.
490
+ typeof segment === "object" ? segment.key : segment
491
+ )
492
+ ).map((key, index) => {
493
+ if (typeof key === "number") return `[${String(key)}]`;
494
+ const rendered = String(key);
495
+ return index === 0 ? rendered : `.${rendered}`;
496
+ }).join("");
497
+ }
498
+
430
499
  // src/parsing/parse-json.ts
431
500
  function parseJson(stdout) {
432
501
  try {
@@ -465,7 +534,24 @@ async function parseYaml(stdout, checkId) {
465
534
  }
466
535
 
467
536
  // src/parsing/parse-output.ts
468
- async function parseOutput(format, stdout, checkId) {
537
+ async function parseOutput(format, stdout, checkId, schema) {
538
+ const parsed = await dispatch(format, stdout, checkId);
539
+ if (!parsed.success || schema === void 0) return parsed;
540
+ let result;
541
+ try {
542
+ result = await schema["~standard"].validate(parsed.value);
543
+ if (typeof result !== "object" || result === null) {
544
+ throw new TypeError(`validate() returned ${String(result)} instead of a Result object`);
545
+ }
546
+ } catch (error) {
547
+ throw new StandardSchemaValidateThrewError(checkId, error);
548
+ }
549
+ if (result.issues === void 0) {
550
+ return { format, success: true, value: result.value };
551
+ }
552
+ return { format, success: false, error: formatSchemaIssues(result.issues) };
553
+ }
554
+ async function dispatch(format, stdout, checkId) {
469
555
  switch (format) {
470
556
  case "json":
471
557
  return parseJson(stdout);
@@ -483,7 +569,12 @@ async function buildEvidence(results, startedAt, completedAt) {
483
569
  results.map(async ([checkId, check, raw]) => {
484
570
  if (check.output === void 0) return [checkId, check, raw];
485
571
  try {
486
- const output = await parseOutput(check.output.format, raw.stdout, checkId);
572
+ const output = await parseOutput(
573
+ check.output.format,
574
+ raw.stdout,
575
+ checkId,
576
+ check.output.schema
577
+ );
487
578
  return [checkId, check, { ...raw, output }];
488
579
  } catch (error) {
489
580
  thrown.push(error);
@@ -496,7 +587,10 @@ async function buildEvidence(results, startedAt, completedAt) {
496
587
  throw only;
497
588
  }
498
589
  if (thrown.length > 1) {
499
- throw new AggregateError(thrown, `${String(thrown.length)} check output(s) failed to parse.`);
590
+ throw new AggregateError(
591
+ thrown,
592
+ `${String(thrown.length)} check output(s) failed during output processing.`
593
+ );
500
594
  }
501
595
  const evidence = {
502
596
  version: 1,
@@ -1096,6 +1190,7 @@ exports.PolicyReadFailedParseValueError = PolicyReadFailedParseValueError;
1096
1190
  exports.PolicyReadUnrequestedOutputError = PolicyReadUnrequestedOutputError;
1097
1191
  exports.PolicyThrewError = PolicyThrewError;
1098
1192
  exports.RepoContractError = RepoContractError;
1193
+ exports.StandardSchemaValidateThrewError = StandardSchemaValidateThrewError;
1099
1194
  exports.UnknownCheckIdError = UnknownCheckIdError;
1100
1195
  exports.defineRepoContract = defineRepoContract;
1101
1196
  exports.runRepoContract = runRepoContract;