@cat-factory/contracts 0.286.0 → 0.287.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/public-spec.d.ts +152 -2
- package/dist/public-spec.d.ts.map +1 -1
- package/dist/public-spec.js +74 -2
- package/dist/public-spec.js.map +1 -1
- package/dist/routes/public-spec.d.ts +110 -0
- package/dist/routes/public-spec.d.ts.map +1 -1
- package/dist/routes/public-spec.js +28 -8
- package/dist/routes/public-spec.js.map +1 -1
- package/package.json +1 -1
package/dist/public-spec.d.ts
CHANGED
|
@@ -43,6 +43,10 @@ export declare const PUBLIC_SPEC_MAX_ISSUES = 200;
|
|
|
43
43
|
* than the one named. A null means the head could not be resolved at all: the tree below is still
|
|
44
44
|
* what the branch held, we simply cannot name the commit.
|
|
45
45
|
*
|
|
46
|
+
* Shared by both reads, which is why `ref` is the field a caller must actually look at rather than
|
|
47
|
+
* assume: WHICH branch each one answers is the distinction between them (see
|
|
48
|
+
* {@link publicRunSpecSchema}).
|
|
49
|
+
*
|
|
46
50
|
* There is no `directory` here, and its absence is the fact: the `spec/` tree is anchored at the
|
|
47
51
|
* REPOSITORY ROOT, so two services carved out of one monorepo share one spec. Naming a
|
|
48
52
|
* subdirectory would imply a scoping the reader does not apply.
|
|
@@ -53,7 +57,13 @@ export declare const publicSpecProvenanceSchema: v.ObjectSchema<{
|
|
|
53
57
|
readonly owner: v.StringSchema<undefined>;
|
|
54
58
|
/** The repository's name. */
|
|
55
59
|
readonly repo: v.StringSchema<undefined>;
|
|
56
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* The branch the spec was read from, named rather than implied because the two reads answer at
|
|
62
|
+
* different refs: the repository's default branch for a service read, and the branch the run
|
|
63
|
+
* pushed its work to for a run read. A run read names the default branch when the run opened no
|
|
64
|
+
* pull request, and when the one it opened has had its head branch deleted (the usual sequel to
|
|
65
|
+
* a merge), which is the same tree under its surviving name.
|
|
66
|
+
*/
|
|
57
67
|
readonly ref: v.StringSchema<undefined>;
|
|
58
68
|
/** The head commit of `ref` at read time, or null when it could not be resolved. */
|
|
59
69
|
readonly commit: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
@@ -201,7 +211,13 @@ export declare const publicServiceSpecSchema: v.ObjectSchema<{
|
|
|
201
211
|
readonly owner: v.StringSchema<undefined>;
|
|
202
212
|
/** The repository's name. */
|
|
203
213
|
readonly repo: v.StringSchema<undefined>;
|
|
204
|
-
/**
|
|
214
|
+
/**
|
|
215
|
+
* The branch the spec was read from, named rather than implied because the two reads answer at
|
|
216
|
+
* different refs: the repository's default branch for a service read, and the branch the run
|
|
217
|
+
* pushed its work to for a run read. A run read names the default branch when the run opened no
|
|
218
|
+
* pull request, and when the one it opened has had its head branch deleted (the usual sequel to
|
|
219
|
+
* a merge), which is the same tree under its surviving name.
|
|
220
|
+
*/
|
|
205
221
|
readonly ref: v.StringSchema<undefined>;
|
|
206
222
|
/** The head commit of `ref` at read time, or null when it could not be resolved. */
|
|
207
223
|
readonly commit: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
@@ -229,4 +245,138 @@ export declare const publicServiceSpecSchema: v.ObjectSchema<{
|
|
|
229
245
|
}, undefined>, undefined>;
|
|
230
246
|
}, undefined>;
|
|
231
247
|
export type PublicServiceSpec = v.InferOutput<typeof publicServiceSpecSchema>;
|
|
248
|
+
/**
|
|
249
|
+
* How the presence anchor resolved for a RUN's spec, for a caller that got a `200`.
|
|
250
|
+
*
|
|
251
|
+
* {@link publicSpecAnchorSchema} plus `not_read`, which is a fact about the RUN rather than about
|
|
252
|
+
* the repository and therefore cannot occur on the service-scoped read:
|
|
253
|
+
*
|
|
254
|
+
* - `not_read` — nothing was read. The run's spec read is gated on a tester having reported, so
|
|
255
|
+
* that the tree served is the one the verdicts were made against; before that point the
|
|
256
|
+
* platform has consulted no tree, which is exactly what `requirements.spec: "not_read"` on the
|
|
257
|
+
* same run's outcome summary already says. `provenance` is null, because there is no snapshot
|
|
258
|
+
* to name.
|
|
259
|
+
*
|
|
260
|
+
* A separate picklist rather than a fourth member on the service one: `not_read` is unreachable
|
|
261
|
+
* there, and an enum carrying a value its endpoint can never answer is a state consumers write
|
|
262
|
+
* dead branches for.
|
|
263
|
+
*/
|
|
264
|
+
export declare const publicRunSpecAnchorSchema: v.PicklistSchema<["present", "absent", "unparsed", "not_read"], undefined>;
|
|
265
|
+
export type PublicRunSpecAnchor = v.InferOutput<typeof publicRunSpecAnchorSchema>;
|
|
266
|
+
/**
|
|
267
|
+
* The spec ONE RUN was judged against, as `/api/v1` serves it.
|
|
268
|
+
*
|
|
269
|
+
* The sibling of {@link publicServiceSpecSchema} rather than a flag on it, for the reason the
|
|
270
|
+
* internal pair already splits on: they answer different questions. The service read answers "what
|
|
271
|
+
* does this service require", from the repository's DEFAULT branch. This answers "what did this run
|
|
272
|
+
* rule on", from the branch the run pushed its work to, which is a different tree for as long as
|
|
273
|
+
* the pull request is open. A caller joining `requirements` rows on `/api/v1/runs/:runId/outcome`
|
|
274
|
+
* or `…/report` back to the criteria they were scored against needs THIS one: every requirement the
|
|
275
|
+
* run itself added is missing from the default branch, so the service read leaves each of those
|
|
276
|
+
* verdicts unjoinable.
|
|
277
|
+
*
|
|
278
|
+
* Same body as the service read (the tree, the Gherkin, the issues, the caps), because it is the
|
|
279
|
+
* same document read at a different ref, and two wire shapes over one artifact are two things to
|
|
280
|
+
* keep in step. What differs is the key (`runId`), the fourth {@link publicRunSpecAnchorSchema}
|
|
281
|
+
* state, and a nullable `provenance`.
|
|
282
|
+
*/
|
|
283
|
+
export declare const publicRunSpecSchema: v.ObjectSchema<{
|
|
284
|
+
/** The run this spec was read for, echoed so a response stands alone. */
|
|
285
|
+
readonly runId: v.StringSchema<undefined>;
|
|
286
|
+
/**
|
|
287
|
+
* What the RUN's branch holds where the spec should be, or `not_read` when the platform has
|
|
288
|
+
* consulted no tree for this run yet. `spec` is non-null exactly when this is `present`.
|
|
289
|
+
*/
|
|
290
|
+
readonly anchor: v.PicklistSchema<["present", "absent", "unparsed", "not_read"], undefined>;
|
|
291
|
+
/** The structured tree, or null when `anchor` is not `present`. */
|
|
292
|
+
readonly spec: v.NullableSchema<v.ObjectSchema<{
|
|
293
|
+
readonly summary: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>]>, "">;
|
|
294
|
+
readonly modules: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
295
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 120, undefined>]>;
|
|
296
|
+
readonly summary: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>]>, "">;
|
|
297
|
+
readonly groups: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
298
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 120, undefined>]>;
|
|
299
|
+
readonly summary: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>]>, "">;
|
|
300
|
+
readonly requirements: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
301
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 200, undefined>]>;
|
|
302
|
+
readonly title: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 120, undefined>]>;
|
|
303
|
+
readonly statement: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 4000, undefined>]>;
|
|
304
|
+
readonly kind: v.PicklistSchema<["functional", "nonfunctional", "constraint"], undefined>;
|
|
305
|
+
readonly priority: v.PicklistSchema<["must", "should", "could"], undefined>;
|
|
306
|
+
readonly state: v.OptionalSchema<v.PicklistSchema<["aspirational", "established"], undefined>, "aspirational">;
|
|
307
|
+
readonly sourceBlockIds: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 200, undefined>]>, undefined>, readonly []>;
|
|
308
|
+
readonly acceptance: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
309
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 200, undefined>]>;
|
|
310
|
+
readonly given: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>]>;
|
|
311
|
+
readonly when: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>]>;
|
|
312
|
+
readonly outcome: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>]>;
|
|
313
|
+
}, undefined>, undefined>, readonly []>;
|
|
314
|
+
}, undefined>, undefined>, readonly []>;
|
|
315
|
+
readonly rules: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
|
|
316
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 200, undefined>]>;
|
|
317
|
+
readonly rule: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 4000, undefined>]>;
|
|
318
|
+
readonly rationale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MaxLengthAction<string, 2000, undefined>]>, "">;
|
|
319
|
+
readonly sourceBlockIds: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MinLengthAction<string, 1, undefined>, v.MaxLengthAction<string, 200, undefined>]>, undefined>, readonly []>;
|
|
320
|
+
}, undefined>, undefined>, readonly []>;
|
|
321
|
+
}, undefined>, undefined>, readonly []>;
|
|
322
|
+
}, undefined>, undefined>, readonly []>;
|
|
323
|
+
readonly service: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.MaxLengthAction<string, 120, undefined>]>, "">;
|
|
324
|
+
}, undefined>, undefined>;
|
|
325
|
+
/** The rendered Gherkin, one entry per `.feature` file. */
|
|
326
|
+
readonly features: v.ArraySchema<v.ObjectSchema<{
|
|
327
|
+
/** The owning module's display name. */
|
|
328
|
+
readonly module: v.StringSchema<undefined>;
|
|
329
|
+
/** The feature/group display name. */
|
|
330
|
+
readonly group: v.StringSchema<undefined>;
|
|
331
|
+
/** Repo-relative path of the `.feature` file. */
|
|
332
|
+
readonly path: v.StringSchema<undefined>;
|
|
333
|
+
/** The Gherkin, clamped to {@link PUBLIC_SPEC_MAX_FEATURE_CHARS}. */
|
|
334
|
+
readonly content: v.StringSchema<undefined>;
|
|
335
|
+
/** Characters actually returned in `content`. */
|
|
336
|
+
readonly chars: v.NumberSchema<undefined>;
|
|
337
|
+
/** Characters the file holds in the repository, whatever was returned. */
|
|
338
|
+
readonly totalChars: v.NumberSchema<undefined>;
|
|
339
|
+
/** True when `chars < totalChars`. */
|
|
340
|
+
readonly truncated: v.BooleanSchema<undefined>;
|
|
341
|
+
}, undefined>, undefined>;
|
|
342
|
+
/**
|
|
343
|
+
* Where the tree was read from: the RUN's branch (its pull request's head while one is open, the
|
|
344
|
+
* repository default otherwise) and the commit it was at.
|
|
345
|
+
*
|
|
346
|
+
* Null exactly when `anchor` is `not_read`, and that is the whole reason it is nullable: there is
|
|
347
|
+
* no snapshot to name, and naming the branch anyway would imply a read that did not happen.
|
|
348
|
+
*/
|
|
349
|
+
readonly provenance: v.NullableSchema<v.ObjectSchema<{
|
|
350
|
+
readonly provider: v.PicklistSchema<["github", "gitlab"], undefined>;
|
|
351
|
+
/** The repository's owner (org or user). */
|
|
352
|
+
readonly owner: v.StringSchema<undefined>;
|
|
353
|
+
/** The repository's name. */
|
|
354
|
+
readonly repo: v.StringSchema<undefined>;
|
|
355
|
+
/**
|
|
356
|
+
* The branch the spec was read from, named rather than implied because the two reads answer at
|
|
357
|
+
* different refs: the repository's default branch for a service read, and the branch the run
|
|
358
|
+
* pushed its work to for a run read. A run read names the default branch when the run opened no
|
|
359
|
+
* pull request, and when the one it opened has had its head branch deleted (the usual sequel to
|
|
360
|
+
* a merge), which is the same tree under its surviving name.
|
|
361
|
+
*/
|
|
362
|
+
readonly ref: v.StringSchema<undefined>;
|
|
363
|
+
/** The head commit of `ref` at read time, or null when it could not be resolved. */
|
|
364
|
+
readonly commit: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
365
|
+
}, undefined>, undefined>;
|
|
366
|
+
/** Files the read could not fully account for. Capped at {@link PUBLIC_SPEC_MAX_ISSUES}. */
|
|
367
|
+
readonly issues: v.ArraySchema<v.ObjectSchema<{
|
|
368
|
+
readonly path: v.StringSchema<undefined>;
|
|
369
|
+
readonly kind: v.PicklistSchema<["read_failed", "unparsed", "partial", "unread"], undefined>;
|
|
370
|
+
readonly dropped: v.OptionalSchema<v.NullableSchema<v.NumberSchema<undefined>, undefined>, 0>;
|
|
371
|
+
}, undefined>, undefined>;
|
|
372
|
+
/** Every cap that bit. Empty when nothing was left out. */
|
|
373
|
+
readonly truncations: v.ArraySchema<v.ObjectSchema<{
|
|
374
|
+
readonly section: v.PicklistSchema<["requirements", "rules", "acceptance", "features", "issues"], undefined>;
|
|
375
|
+
/** How many rows the response carries. */
|
|
376
|
+
readonly shown: v.NumberSchema<undefined>;
|
|
377
|
+
/** How many rows the spec holds. */
|
|
378
|
+
readonly total: v.NumberSchema<undefined>;
|
|
379
|
+
}, undefined>, undefined>;
|
|
380
|
+
}, undefined>;
|
|
381
|
+
export type PublicRunSpec = v.InferOutput<typeof publicRunSpecSchema>;
|
|
232
382
|
//# sourceMappingURL=public-spec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-spec.d.ts","sourceRoot":"","sources":["../src/public-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"public-spec.d.ts","sourceRoot":"","sources":["../src/public-spec.ts"],"names":[],"mappings":"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"}
|
package/dist/public-spec.js
CHANGED
|
@@ -2,7 +2,10 @@ import * as v from 'valibot';
|
|
|
2
2
|
import { vcsProviderSchema } from './routes/auth.js';
|
|
3
3
|
import { readSpecDocSchema, specReadIssueSchema } from './spec.js';
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
|
-
// The public
|
|
5
|
+
// The public reads of the in-repo SPECIFICATION: a service's, from the repository's default branch
|
|
6
|
+
// (`GET /api/v1/services/:serviceId/spec`), and a run's, from the branch that run pushed its work
|
|
7
|
+
// to (`GET /api/v1/runs/:runId/spec`). Everything below describes the first; the second carries the
|
|
8
|
+
// same body at a different ref, and {@link publicRunSpecSchema} states what it changes and why.
|
|
6
9
|
//
|
|
7
10
|
// The spec is the platform's requirements truth: structured requirement items with a MoSCoW
|
|
8
11
|
// priority, an `aspirational ⇄ established` lifecycle state and Gherkin-shaped acceptance
|
|
@@ -86,6 +89,10 @@ export const PUBLIC_SPEC_MAX_ISSUES = 200;
|
|
|
86
89
|
* than the one named. A null means the head could not be resolved at all: the tree below is still
|
|
87
90
|
* what the branch held, we simply cannot name the commit.
|
|
88
91
|
*
|
|
92
|
+
* Shared by both reads, which is why `ref` is the field a caller must actually look at rather than
|
|
93
|
+
* assume: WHICH branch each one answers is the distinction between them (see
|
|
94
|
+
* {@link publicRunSpecSchema}).
|
|
95
|
+
*
|
|
89
96
|
* There is no `directory` here, and its absence is the fact: the `spec/` tree is anchored at the
|
|
90
97
|
* REPOSITORY ROOT, so two services carved out of one monorepo share one spec. Naming a
|
|
91
98
|
* subdirectory would imply a scoping the reader does not apply.
|
|
@@ -96,7 +103,13 @@ export const publicSpecProvenanceSchema = v.object({
|
|
|
96
103
|
owner: v.string(),
|
|
97
104
|
/** The repository's name. */
|
|
98
105
|
repo: v.string(),
|
|
99
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* The branch the spec was read from, named rather than implied because the two reads answer at
|
|
108
|
+
* different refs: the repository's default branch for a service read, and the branch the run
|
|
109
|
+
* pushed its work to for a run read. A run read names the default branch when the run opened no
|
|
110
|
+
* pull request, and when the one it opened has had its head branch deleted (the usual sequel to
|
|
111
|
+
* a merge), which is the same tree under its surviving name.
|
|
112
|
+
*/
|
|
100
113
|
ref: v.string(),
|
|
101
114
|
/** The head commit of `ref` at read time, or null when it could not be resolved. */
|
|
102
115
|
commit: v.nullable(v.string()),
|
|
@@ -205,4 +218,63 @@ export const publicServiceSpecSchema = v.object({
|
|
|
205
218
|
/** Every cap that bit. Empty when nothing was left out. */
|
|
206
219
|
truncations: v.array(publicSpecTruncationSchema),
|
|
207
220
|
});
|
|
221
|
+
/**
|
|
222
|
+
* How the presence anchor resolved for a RUN's spec, for a caller that got a `200`.
|
|
223
|
+
*
|
|
224
|
+
* {@link publicSpecAnchorSchema} plus `not_read`, which is a fact about the RUN rather than about
|
|
225
|
+
* the repository and therefore cannot occur on the service-scoped read:
|
|
226
|
+
*
|
|
227
|
+
* - `not_read` — nothing was read. The run's spec read is gated on a tester having reported, so
|
|
228
|
+
* that the tree served is the one the verdicts were made against; before that point the
|
|
229
|
+
* platform has consulted no tree, which is exactly what `requirements.spec: "not_read"` on the
|
|
230
|
+
* same run's outcome summary already says. `provenance` is null, because there is no snapshot
|
|
231
|
+
* to name.
|
|
232
|
+
*
|
|
233
|
+
* A separate picklist rather than a fourth member on the service one: `not_read` is unreachable
|
|
234
|
+
* there, and an enum carrying a value its endpoint can never answer is a state consumers write
|
|
235
|
+
* dead branches for.
|
|
236
|
+
*/
|
|
237
|
+
export const publicRunSpecAnchorSchema = v.picklist(['present', 'absent', 'unparsed', 'not_read']);
|
|
238
|
+
/**
|
|
239
|
+
* The spec ONE RUN was judged against, as `/api/v1` serves it.
|
|
240
|
+
*
|
|
241
|
+
* The sibling of {@link publicServiceSpecSchema} rather than a flag on it, for the reason the
|
|
242
|
+
* internal pair already splits on: they answer different questions. The service read answers "what
|
|
243
|
+
* does this service require", from the repository's DEFAULT branch. This answers "what did this run
|
|
244
|
+
* rule on", from the branch the run pushed its work to, which is a different tree for as long as
|
|
245
|
+
* the pull request is open. A caller joining `requirements` rows on `/api/v1/runs/:runId/outcome`
|
|
246
|
+
* or `…/report` back to the criteria they were scored against needs THIS one: every requirement the
|
|
247
|
+
* run itself added is missing from the default branch, so the service read leaves each of those
|
|
248
|
+
* verdicts unjoinable.
|
|
249
|
+
*
|
|
250
|
+
* Same body as the service read (the tree, the Gherkin, the issues, the caps), because it is the
|
|
251
|
+
* same document read at a different ref, and two wire shapes over one artifact are two things to
|
|
252
|
+
* keep in step. What differs is the key (`runId`), the fourth {@link publicRunSpecAnchorSchema}
|
|
253
|
+
* state, and a nullable `provenance`.
|
|
254
|
+
*/
|
|
255
|
+
export const publicRunSpecSchema = v.object({
|
|
256
|
+
/** The run this spec was read for, echoed so a response stands alone. */
|
|
257
|
+
runId: v.string(),
|
|
258
|
+
/**
|
|
259
|
+
* What the RUN's branch holds where the spec should be, or `not_read` when the platform has
|
|
260
|
+
* consulted no tree for this run yet. `spec` is non-null exactly when this is `present`.
|
|
261
|
+
*/
|
|
262
|
+
anchor: publicRunSpecAnchorSchema,
|
|
263
|
+
/** The structured tree, or null when `anchor` is not `present`. */
|
|
264
|
+
spec: v.nullable(readSpecDocSchema),
|
|
265
|
+
/** The rendered Gherkin, one entry per `.feature` file. */
|
|
266
|
+
features: v.array(publicSpecFeatureFileSchema),
|
|
267
|
+
/**
|
|
268
|
+
* Where the tree was read from: the RUN's branch (its pull request's head while one is open, the
|
|
269
|
+
* repository default otherwise) and the commit it was at.
|
|
270
|
+
*
|
|
271
|
+
* Null exactly when `anchor` is `not_read`, and that is the whole reason it is nullable: there is
|
|
272
|
+
* no snapshot to name, and naming the branch anyway would imply a read that did not happen.
|
|
273
|
+
*/
|
|
274
|
+
provenance: v.nullable(publicSpecProvenanceSchema),
|
|
275
|
+
/** Files the read could not fully account for. Capped at {@link PUBLIC_SPEC_MAX_ISSUES}. */
|
|
276
|
+
issues: v.array(specReadIssueSchema),
|
|
277
|
+
/** Every cap that bit. Empty when nothing was left out. */
|
|
278
|
+
truncations: v.array(publicSpecTruncationSchema),
|
|
279
|
+
});
|
|
208
280
|
//# sourceMappingURL=public-spec.js.map
|
package/dist/public-spec.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-spec.js","sourceRoot":"","sources":["../src/public-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAElE,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"public-spec.js","sourceRoot":"","sources":["../src/public-spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -107,4 +107,114 @@ export declare const getPublicServiceSpecContract: {
|
|
|
107
107
|
} & {
|
|
108
108
|
readonly minScope: "read";
|
|
109
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* The specification ONE RUN was judged against, read from the branch that run pushed its work to.
|
|
112
|
+
*
|
|
113
|
+
* The sibling of {@link getPublicServiceSpecContract}, and the reason it is a sibling rather than a
|
|
114
|
+
* query parameter is the reason the internal pair already splits: they answer different questions,
|
|
115
|
+
* and a caller that asked the first while meaning the second got a document missing exactly the
|
|
116
|
+
* requirements the run had added. Every verdict naming one of those landed as unjoinable.
|
|
117
|
+
*
|
|
118
|
+
* `read` scope, and addressed under `/api/v1/runs/:runId/*` beside `…/report` and `…/outcome`, so
|
|
119
|
+
* the requirement ids on those two and the criteria they were scored against are three GETs on one
|
|
120
|
+
* key rather than a repository clone.
|
|
121
|
+
*/
|
|
122
|
+
export declare const getPublicRunSpecContract: {
|
|
123
|
+
readonly method: "get";
|
|
124
|
+
readonly requestPathParamsSchema: import("valibot").ObjectSchema<{
|
|
125
|
+
runId: import("valibot").StringSchema<undefined>;
|
|
126
|
+
}, undefined> & import("@toad-contracts/core").StandardObjectKeysV1<unknown, unknown>;
|
|
127
|
+
readonly pathResolver: ({ runId }: {
|
|
128
|
+
runId: string;
|
|
129
|
+
}) => string;
|
|
130
|
+
readonly responsesByStatusCode: {
|
|
131
|
+
readonly '4xx': import("valibot").ObjectSchema<{
|
|
132
|
+
readonly error: import("valibot").ObjectSchema<{
|
|
133
|
+
readonly code: import("valibot").StringSchema<undefined>;
|
|
134
|
+
readonly message: import("valibot").StringSchema<undefined>;
|
|
135
|
+
readonly details: import("valibot").OptionalSchema<import("valibot").UnknownSchema, undefined>;
|
|
136
|
+
readonly issues: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
137
|
+
readonly path: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
138
|
+
readonly message: import("valibot").StringSchema<undefined>;
|
|
139
|
+
}, undefined>, undefined>, undefined>;
|
|
140
|
+
}, undefined>;
|
|
141
|
+
}, undefined>;
|
|
142
|
+
readonly '5xx': import("valibot").ObjectSchema<{
|
|
143
|
+
readonly error: import("valibot").ObjectSchema<{
|
|
144
|
+
readonly code: import("valibot").StringSchema<undefined>;
|
|
145
|
+
readonly message: import("valibot").StringSchema<undefined>;
|
|
146
|
+
readonly details: import("valibot").OptionalSchema<import("valibot").UnknownSchema, undefined>;
|
|
147
|
+
readonly issues: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
148
|
+
readonly path: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
149
|
+
readonly message: import("valibot").StringSchema<undefined>;
|
|
150
|
+
}, undefined>, undefined>, undefined>;
|
|
151
|
+
}, undefined>;
|
|
152
|
+
}, undefined>;
|
|
153
|
+
readonly 200: import("valibot").ObjectSchema<{
|
|
154
|
+
readonly runId: import("valibot").StringSchema<undefined>;
|
|
155
|
+
readonly anchor: import("valibot").PicklistSchema<["present", "absent", "unparsed", "not_read"], undefined>;
|
|
156
|
+
readonly spec: import("valibot").NullableSchema<import("valibot").ObjectSchema<{
|
|
157
|
+
readonly summary: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MaxLengthAction<string, 2000, undefined>]>, "">;
|
|
158
|
+
readonly modules: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
159
|
+
readonly name: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 120, undefined>]>;
|
|
160
|
+
readonly summary: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MaxLengthAction<string, 2000, undefined>]>, "">;
|
|
161
|
+
readonly groups: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
162
|
+
readonly name: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 120, undefined>]>;
|
|
163
|
+
readonly summary: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MaxLengthAction<string, 2000, undefined>]>, "">;
|
|
164
|
+
readonly requirements: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
165
|
+
readonly id: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>;
|
|
166
|
+
readonly title: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 120, undefined>]>;
|
|
167
|
+
readonly statement: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 4000, undefined>]>;
|
|
168
|
+
readonly kind: import("valibot").PicklistSchema<["functional", "nonfunctional", "constraint"], undefined>;
|
|
169
|
+
readonly priority: import("valibot").PicklistSchema<["must", "should", "could"], undefined>;
|
|
170
|
+
readonly state: import("valibot").OptionalSchema<import("valibot").PicklistSchema<["aspirational", "established"], undefined>, "aspirational">;
|
|
171
|
+
readonly sourceBlockIds: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>, undefined>, readonly []>;
|
|
172
|
+
readonly acceptance: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
173
|
+
readonly id: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>;
|
|
174
|
+
readonly given: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MaxLengthAction<string, 2000, undefined>]>;
|
|
175
|
+
readonly when: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MaxLengthAction<string, 2000, undefined>]>;
|
|
176
|
+
readonly outcome: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MaxLengthAction<string, 2000, undefined>]>;
|
|
177
|
+
}, undefined>, undefined>, readonly []>;
|
|
178
|
+
}, undefined>, undefined>, readonly []>;
|
|
179
|
+
readonly rules: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
180
|
+
readonly id: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>;
|
|
181
|
+
readonly rule: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 4000, undefined>]>;
|
|
182
|
+
readonly rationale: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MaxLengthAction<string, 2000, undefined>]>, "">;
|
|
183
|
+
readonly sourceBlockIds: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 200, undefined>]>, undefined>, readonly []>;
|
|
184
|
+
}, undefined>, undefined>, readonly []>;
|
|
185
|
+
}, undefined>, undefined>, readonly []>;
|
|
186
|
+
}, undefined>, undefined>, readonly []>;
|
|
187
|
+
readonly service: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").TrimAction, import("valibot").MaxLengthAction<string, 120, undefined>]>, "">;
|
|
188
|
+
}, undefined>, undefined>;
|
|
189
|
+
readonly features: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
190
|
+
readonly module: import("valibot").StringSchema<undefined>;
|
|
191
|
+
readonly group: import("valibot").StringSchema<undefined>;
|
|
192
|
+
readonly path: import("valibot").StringSchema<undefined>;
|
|
193
|
+
readonly content: import("valibot").StringSchema<undefined>;
|
|
194
|
+
readonly chars: import("valibot").NumberSchema<undefined>;
|
|
195
|
+
readonly totalChars: import("valibot").NumberSchema<undefined>;
|
|
196
|
+
readonly truncated: import("valibot").BooleanSchema<undefined>;
|
|
197
|
+
}, undefined>, undefined>;
|
|
198
|
+
readonly provenance: import("valibot").NullableSchema<import("valibot").ObjectSchema<{
|
|
199
|
+
readonly provider: import("valibot").PicklistSchema<["github", "gitlab"], undefined>;
|
|
200
|
+
readonly owner: import("valibot").StringSchema<undefined>;
|
|
201
|
+
readonly repo: import("valibot").StringSchema<undefined>;
|
|
202
|
+
readonly ref: import("valibot").StringSchema<undefined>;
|
|
203
|
+
readonly commit: import("valibot").NullableSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
204
|
+
}, undefined>, undefined>;
|
|
205
|
+
readonly issues: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
206
|
+
readonly path: import("valibot").StringSchema<undefined>;
|
|
207
|
+
readonly kind: import("valibot").PicklistSchema<["read_failed", "unparsed", "partial", "unread"], undefined>;
|
|
208
|
+
readonly dropped: import("valibot").OptionalSchema<import("valibot").NullableSchema<import("valibot").NumberSchema<undefined>, undefined>, 0>;
|
|
209
|
+
}, undefined>, undefined>;
|
|
210
|
+
readonly truncations: import("valibot").ArraySchema<import("valibot").ObjectSchema<{
|
|
211
|
+
readonly section: import("valibot").PicklistSchema<["requirements", "rules", "acceptance", "features", "issues"], undefined>;
|
|
212
|
+
readonly shown: import("valibot").NumberSchema<undefined>;
|
|
213
|
+
readonly total: import("valibot").NumberSchema<undefined>;
|
|
214
|
+
}, undefined>, undefined>;
|
|
215
|
+
}, undefined>;
|
|
216
|
+
};
|
|
217
|
+
} & {
|
|
218
|
+
readonly minScope: "read";
|
|
219
|
+
};
|
|
110
220
|
//# sourceMappingURL=public-spec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-spec.d.ts","sourceRoot":"","sources":["../../src/routes/public-spec.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"public-spec.d.ts","sourceRoot":"","sources":["../../src/routes/public-spec.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQxC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQpC,CAAA"}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { defineApiContract } from '@toad-contracts/valibot';
|
|
2
|
-
import { publicServiceSpecSchema } from '../public-spec.js';
|
|
2
|
+
import { publicRunSpecSchema, publicServiceSpecSchema } from '../public-spec.js';
|
|
3
3
|
import { errorResponses, singleStringParam, withMinScope } from './_shared.js';
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
|
-
// The public SPEC
|
|
6
|
-
// The wire
|
|
7
|
-
// controller implements (
|
|
5
|
+
// The public SPEC reads: absolute `/api/v1` paths, authenticated in-controller by a public-API key.
|
|
6
|
+
// The wire shapes and the reasoning behind them live in `../public-spec.ts`; the honesty contract
|
|
7
|
+
// the controller implements (the outcomes, never folded) is in `PublicSpecController`.
|
|
8
8
|
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
9
|
+
// Each is addressed under the resource the question is ABOUT, which is why there are two of them
|
|
10
|
+
// rather than one with a `ref` parameter. The service read is a fact about a SERVICE and sits
|
|
11
|
+
// beside `…/tasks`; the `serviceId` is the board service-frame id every other endpoint on this
|
|
12
|
+
// surface already uses, and it resolves through the same board read, so a key can only ever name a
|
|
13
|
+
// service of its own workspace. The run read is a fact about a RUN and sits beside `…/report` and
|
|
14
|
+
// `…/outcome`, so criterion to evidence is three GETs on one key.
|
|
13
15
|
// ---------------------------------------------------------------------------
|
|
14
16
|
/**
|
|
15
17
|
* The service's in-repo specification: the structured requirement tree, the rendered Gherkin, and
|
|
@@ -28,4 +30,22 @@ export const getPublicServiceSpecContract = withMinScope('read', defineApiContra
|
|
|
28
30
|
pathResolver: ({ serviceId }) => `/api/v1/services/${serviceId}/spec`,
|
|
29
31
|
responsesByStatusCode: { 200: publicServiceSpecSchema, ...errorResponses },
|
|
30
32
|
}));
|
|
33
|
+
/**
|
|
34
|
+
* The specification ONE RUN was judged against, read from the branch that run pushed its work to.
|
|
35
|
+
*
|
|
36
|
+
* The sibling of {@link getPublicServiceSpecContract}, and the reason it is a sibling rather than a
|
|
37
|
+
* query parameter is the reason the internal pair already splits: they answer different questions,
|
|
38
|
+
* and a caller that asked the first while meaning the second got a document missing exactly the
|
|
39
|
+
* requirements the run had added. Every verdict naming one of those landed as unjoinable.
|
|
40
|
+
*
|
|
41
|
+
* `read` scope, and addressed under `/api/v1/runs/:runId/*` beside `…/report` and `…/outcome`, so
|
|
42
|
+
* the requirement ids on those two and the criteria they were scored against are three GETs on one
|
|
43
|
+
* key rather than a repository clone.
|
|
44
|
+
*/
|
|
45
|
+
export const getPublicRunSpecContract = withMinScope('read', defineApiContract({
|
|
46
|
+
method: 'get',
|
|
47
|
+
requestPathParamsSchema: singleStringParam('runId'),
|
|
48
|
+
pathResolver: ({ runId }) => `/api/v1/runs/${runId}/spec`,
|
|
49
|
+
responsesByStatusCode: { 200: publicRunSpecSchema, ...errorResponses },
|
|
50
|
+
}));
|
|
31
51
|
//# sourceMappingURL=public-spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-spec.js","sourceRoot":"","sources":["../../src/routes/public-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"public-spec.js","sourceRoot":"","sources":["../../src/routes/public-spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAChF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE9E,8EAA8E;AAC9E,oGAAoG;AACpG,kGAAkG;AAClG,uFAAuF;AACvF,EAAE;AACF,iGAAiG;AACjG,8FAA8F;AAC9F,+FAA+F;AAC/F,mGAAmG;AACnG,kGAAkG;AAClG,kEAAkE;AAClE,8EAA8E;AAE9E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,YAAY,CACtD,MAAM,EACN,iBAAiB,CAAC;IAChB,MAAM,EAAE,KAAK;IACb,uBAAuB,EAAE,iBAAiB,CAAC,WAAW,CAAC;IACvD,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,oBAAoB,SAAS,OAAO;IACrE,qBAAqB,EAAE,EAAE,GAAG,EAAE,uBAAuB,EAAE,GAAG,cAAc,EAAE;CAC3E,CAAC,CACH,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,YAAY,CAClD,MAAM,EACN,iBAAiB,CAAC;IAChB,MAAM,EAAE,KAAK;IACb,uBAAuB,EAAE,iBAAiB,CAAC,OAAO,CAAC;IACnD,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,gBAAgB,KAAK,OAAO;IACzD,qBAAqB,EAAE,EAAE,GAAG,EAAE,mBAAmB,EAAE,GAAG,cAAc,EAAE;CACvE,CAAC,CACH,CAAA"}
|