@osdlc/typed-gh 0.11.1 → 0.12.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.
- package/CHANGELOG.md +16 -0
- package/README.md +32 -1
- package/dist/parse.js +9 -1
- package/dist/testing.d.ts +216 -0
- package/dist/testing.js +186 -0
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @osdlc/typed-gh
|
|
2
2
|
|
|
3
|
+
## 0.12.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [82d9841]
|
|
8
|
+
- Updated dependencies [ebe0e0d]
|
|
9
|
+
- @osdlc/typed-git@0.11.0
|
|
10
|
+
|
|
11
|
+
## 0.12.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- a4ca07d: New `@osdlc/typed-gh/testing` entry point with builders for faking `gh` in tests. `prRow`, `issueRow`, `repoRow`, `searchPrRow`, `labelRow`, `checkRunRow`, `statusContextRow`, `commentRow` and `reviewRow` return gh's raw `--json` rows, with defaults that fill every field the parsers require (a pull request's `number`, a repository's `nameWithOwner`, the `headRefName` that `prList({ head })` filters on), and take typed overrides merged shallowly. `ghResult(payload)` wraps rows in a successful `CommandResult` for a fake runner. The main entry point does not import it.
|
|
16
|
+
|
|
17
|
+
Fixed: `searchPrs` reads gh's zero time (`0001-01-01T00:00:00Z`), which gh prints for a hit that isn't closed, as `closedAt: null`. Before, an open hit had a year-0001 close date.
|
|
18
|
+
|
|
3
19
|
## 0.11.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -488,6 +488,36 @@ Import the runners themselves, such as `spawnRunner` and `spawnRunnerAsync`, fro
|
|
|
488
488
|
named `gh` in the working directory cannot run in its place. Pass `{ absolutePathOnly: true }` when
|
|
489
489
|
you build a real runner yourself.
|
|
490
490
|
|
|
491
|
+
## Testing
|
|
492
|
+
|
|
493
|
+
`@osdlc/typed-gh/testing` builds the rows a fake runner answers with. Each builder returns gh's raw
|
|
494
|
+
`--json` shape, so the real parsers read it. Its defaults fill every field a parser requires, such
|
|
495
|
+
as a pull request's `number`, a repository's `nameWithOwner` and the `headRefName` that
|
|
496
|
+
`prList({ head })` filters on. Without them a row is dropped with no error.
|
|
497
|
+
|
|
498
|
+
- `prRow`, `issueRow`, `repoRow`, `searchPrRow` and `labelRow`: one row of `gh pr`, `gh issue`,
|
|
499
|
+
`gh repo`, `gh search prs` and `gh label` output.
|
|
500
|
+
- `checkRunRow`, `statusContextRow`, `commentRow` and `reviewRow`: entries of a pull request's
|
|
501
|
+
`statusCheckRollup`, `comments` and `reviews`.
|
|
502
|
+
- `ghResult(payload)`: a `CommandResult` with exit code 0 and the payload as JSON on stdout.
|
|
503
|
+
- Row types: `GhPrJson`, `GhIssueJson`, `GhRepoJson`, `GhSearchPrJson`, `GhLabelJson`,
|
|
504
|
+
`GhCheckRunJson`, `GhStatusContextJson`, `GhCommentJson`, `GhReviewJson` and `GhActorJson`, and
|
|
505
|
+
`RowOverrides<T>`, what a builder takes.
|
|
506
|
+
|
|
507
|
+
Each builder takes typed overrides, merged shallowly. Pass a field as `undefined` to leave it out.
|
|
508
|
+
A pull request's `url` follows its `number`, and a repository's its `nameWithOwner`. Assert on what
|
|
509
|
+
you set: a default value may change in a minor release.
|
|
510
|
+
|
|
511
|
+
```ts
|
|
512
|
+
import { ghResult, prRow } from '@osdlc/typed-gh/testing'
|
|
513
|
+
|
|
514
|
+
const runner: CommandRunner = {
|
|
515
|
+
run: () => ghResult([prRow({ number: 7, headRefName: 'task/foo' }), prRow({ number: 8 })]),
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
new Gh('/repo', { runner }).openPrFor('task/foo')?.number // 7
|
|
519
|
+
```
|
|
520
|
+
|
|
491
521
|
## API
|
|
492
522
|
|
|
493
523
|
Everything below is exported from `@osdlc/typed-gh`. The Stability section says which items are
|
|
@@ -599,7 +629,8 @@ The experimental items:
|
|
|
599
629
|
- `GraphqlOptions`
|
|
600
630
|
- `GraphqlVariable`
|
|
601
631
|
|
|
602
|
-
Every other export and method is stable, `prDiff` included.
|
|
632
|
+
Every other export and method is stable, `prDiff` included. So is `@osdlc/typed-gh/testing`: its
|
|
633
|
+
builders and their row types. Their default values may change in any minor release.
|
|
603
634
|
|
|
604
635
|
## Platforms
|
|
605
636
|
|
package/dist/parse.js
CHANGED
|
@@ -266,6 +266,14 @@ export function parsePrSearchHit(raw) {
|
|
|
266
266
|
labels: parseLabels(raw['labels']),
|
|
267
267
|
createdAt: strOrNull(raw['createdAt']),
|
|
268
268
|
updatedAt: strOrNull(raw['updatedAt']),
|
|
269
|
-
closedAt:
|
|
269
|
+
closedAt: searchTime(raw['closedAt']),
|
|
270
270
|
};
|
|
271
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* gh search prints Go's zero time (`0001-01-01T00:00:00Z`) for a time that is
|
|
274
|
+
* not set, such as `closedAt` on an open pull request. That is no time.
|
|
275
|
+
*/
|
|
276
|
+
function searchTime(x) {
|
|
277
|
+
const s = strOrNull(x);
|
|
278
|
+
return s === null || s.startsWith('0001-01-01') ? null : s;
|
|
279
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@osdlc/typed-gh/testing`: rows of `gh --json` output, for faking `gh` in
|
|
3
|
+
* tests.
|
|
4
|
+
*
|
|
5
|
+
* A separate subpath, not part of the package entry, so production code does
|
|
6
|
+
* not carry fixture data. Nothing in `src/` but this file knows about it.
|
|
7
|
+
*
|
|
8
|
+
* Each builder returns gh's raw JSON shape, what `gh … --json` prints
|
|
9
|
+
* (`nameWithOwner`, `headRefName`, `defaultBranchRef: { name }`), not the
|
|
10
|
+
* parsed model. Feed the rows to a fake runner through {@link ghResult} and
|
|
11
|
+
* the real parsers read them, so a test exercises the same parsing a real
|
|
12
|
+
* `gh` call does.
|
|
13
|
+
*
|
|
14
|
+
* The defaults fill every field the parsers require, which is where hand-made
|
|
15
|
+
* rows go wrong: a row the parser rejects is dropped without an error.
|
|
16
|
+
*
|
|
17
|
+
* - A pull request needs an integer `number` (`parsePullRequest`), and
|
|
18
|
+
* `prList({ head })` also keeps only rows whose `headRefName` equals
|
|
19
|
+
* `head`.
|
|
20
|
+
* - An issue and a search hit need a numeric `number`.
|
|
21
|
+
* - A repository needs `nameWithOwner` as `owner/name`, both parts
|
|
22
|
+
* non-empty (`parseRepository`).
|
|
23
|
+
* - A label needs a non-empty `name` (`parseLabels`).
|
|
24
|
+
* - A check needs a `name`, or a `context` for a legacy status context
|
|
25
|
+
* (`parseCheckRun`).
|
|
26
|
+
*
|
|
27
|
+
* Overrides merge shallowly: a field you pass replaces the default whole, and
|
|
28
|
+
* a field you pass as `undefined` is left out of the row, to test a payload
|
|
29
|
+
* that lacks it. A default that names another field (a pull request's `url`
|
|
30
|
+
* names its `number`) follows your override of that field. The default
|
|
31
|
+
* values may change in a minor release, as long as every parser still
|
|
32
|
+
* accepts them, so assert on what you set, not on a default.
|
|
33
|
+
*/
|
|
34
|
+
import type { CommandResult } from '@osdlc/command-seam';
|
|
35
|
+
import type { CheckConclusion, MergeableState, MergeStateStatus, PullRequestState, RepositoryVisibility, ReviewState } from './types.ts';
|
|
36
|
+
/**
|
|
37
|
+
* What a builder takes: any field of the row, or `undefined` to leave that
|
|
38
|
+
* field out.
|
|
39
|
+
*/
|
|
40
|
+
export type RowOverrides<T> = {
|
|
41
|
+
[K in keyof T]?: T[K] | undefined;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* A successful `gh` call that printed `payload` as JSON: exit code 0, the
|
|
45
|
+
* payload on stdout with gh's trailing newline, and nothing on stderr. Pass an
|
|
46
|
+
* array of rows for a list verb and one row for a view verb.
|
|
47
|
+
*/
|
|
48
|
+
export declare function ghResult(payload: unknown): CommandResult;
|
|
49
|
+
/**
|
|
50
|
+
* A pull request's or search hit's `author` as `gh --json` prints it. A bot
|
|
51
|
+
* is `{ is_bot: true, login: 'app/<name>' }`.
|
|
52
|
+
*/
|
|
53
|
+
export interface GhActorJson {
|
|
54
|
+
login: string;
|
|
55
|
+
is_bot?: boolean;
|
|
56
|
+
name?: string;
|
|
57
|
+
id?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A comment's or review's `author` as `gh --json` prints it: only `login`.
|
|
61
|
+
* gh leaves out `id`, `name` and `is_bot` there, so a bot comment does not
|
|
62
|
+
* read as a bot unless its login ends in `[bot]`.
|
|
63
|
+
*/
|
|
64
|
+
export interface GhCommentAuthorJson {
|
|
65
|
+
login: string;
|
|
66
|
+
}
|
|
67
|
+
/** One entry of a `labels` field, or one row of `gh label list --json name,color,description`. */
|
|
68
|
+
export interface GhLabelJson {
|
|
69
|
+
name: string;
|
|
70
|
+
/** Six hex digits, no `#`. */
|
|
71
|
+
color: string;
|
|
72
|
+
description: string;
|
|
73
|
+
}
|
|
74
|
+
/** A label row. The default is GitHub's own `bug` label. */
|
|
75
|
+
export declare function labelRow(overrides?: RowOverrides<GhLabelJson>): GhLabelJson;
|
|
76
|
+
/** A modern `CheckRun` node of `statusCheckRollup`. */
|
|
77
|
+
export interface GhCheckRunJson {
|
|
78
|
+
__typename: 'CheckRun';
|
|
79
|
+
name: string;
|
|
80
|
+
workflowName: string;
|
|
81
|
+
/** `QUEUED`, `IN_PROGRESS` or `COMPLETED`. */
|
|
82
|
+
status: string;
|
|
83
|
+
/** gh prints `""` while the check runs. */
|
|
84
|
+
conclusion: Exclude<CheckConclusion, null> | '';
|
|
85
|
+
detailsUrl: string;
|
|
86
|
+
startedAt: string;
|
|
87
|
+
completedAt: string;
|
|
88
|
+
}
|
|
89
|
+
/** A check run. The default completed with `SUCCESS`, so it reads as a green check. */
|
|
90
|
+
export declare function checkRunRow(overrides?: RowOverrides<GhCheckRunJson>): GhCheckRunJson;
|
|
91
|
+
/** A legacy `StatusContext` node of `statusCheckRollup`. */
|
|
92
|
+
export interface GhStatusContextJson {
|
|
93
|
+
__typename: 'StatusContext';
|
|
94
|
+
context: string;
|
|
95
|
+
/** `SUCCESS`, `PENDING`, `FAILURE` or `ERROR`. */
|
|
96
|
+
state: string;
|
|
97
|
+
targetUrl: string;
|
|
98
|
+
startedAt: string;
|
|
99
|
+
}
|
|
100
|
+
/** A legacy status context. The default is a `SUCCESS`. */
|
|
101
|
+
export declare function statusContextRow(overrides?: RowOverrides<GhStatusContextJson>): GhStatusContextJson;
|
|
102
|
+
/** One entry of a pull request's `comments`. */
|
|
103
|
+
export interface GhCommentJson {
|
|
104
|
+
/** The GraphQL node id. */
|
|
105
|
+
id: string;
|
|
106
|
+
author: GhCommentAuthorJson | null;
|
|
107
|
+
authorAssociation: string;
|
|
108
|
+
body: string;
|
|
109
|
+
createdAt: string;
|
|
110
|
+
url: string;
|
|
111
|
+
}
|
|
112
|
+
/** A comment by `octocat`. */
|
|
113
|
+
export declare function commentRow(overrides?: RowOverrides<GhCommentJson>): GhCommentJson;
|
|
114
|
+
/** One entry of a pull request's `reviews`. */
|
|
115
|
+
export interface GhReviewJson {
|
|
116
|
+
/** The GraphQL node id. */
|
|
117
|
+
id: string;
|
|
118
|
+
author: GhCommentAuthorJson | null;
|
|
119
|
+
authorAssociation: string;
|
|
120
|
+
body: string;
|
|
121
|
+
state: ReviewState;
|
|
122
|
+
submittedAt: string;
|
|
123
|
+
commit: {
|
|
124
|
+
oid: string;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/** An approving review by `octocat`. */
|
|
128
|
+
export declare function reviewRow(overrides?: RowOverrides<GhReviewJson>): GhReviewJson;
|
|
129
|
+
/** A pull request as `gh pr list`/`view --json` prints it, with every field the parser reads. */
|
|
130
|
+
export interface GhPrJson {
|
|
131
|
+
/** Required: a row without an integer `number` is dropped. */
|
|
132
|
+
number: number;
|
|
133
|
+
state: PullRequestState;
|
|
134
|
+
title: string;
|
|
135
|
+
body: string;
|
|
136
|
+
url: string;
|
|
137
|
+
isDraft: boolean;
|
|
138
|
+
baseRefName: string;
|
|
139
|
+
/** Required by `prList({ head })`, which keeps only rows whose head is exactly `head`. */
|
|
140
|
+
headRefName: string;
|
|
141
|
+
headRefOid: string;
|
|
142
|
+
isCrossRepository: boolean;
|
|
143
|
+
mergeable: MergeableState;
|
|
144
|
+
mergeStateStatus: MergeStateStatus;
|
|
145
|
+
/** gh prints `""` when there is no decision. */
|
|
146
|
+
reviewDecision: 'APPROVED' | 'CHANGES_REQUESTED' | 'REVIEW_REQUIRED' | '';
|
|
147
|
+
author: GhActorJson | null;
|
|
148
|
+
labels: GhLabelJson[];
|
|
149
|
+
comments: GhCommentJson[];
|
|
150
|
+
reviews: GhReviewJson[];
|
|
151
|
+
statusCheckRollup: (GhCheckRunJson | GhStatusContextJson)[];
|
|
152
|
+
mergedAt: string | null;
|
|
153
|
+
createdAt: string;
|
|
154
|
+
updatedAt: string;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* An open, mergeable pull request #1 from `feature/add-retries` into `main`
|
|
158
|
+
* of `octo-org/hello-world`, by `octocat`, with no labels, comments, reviews
|
|
159
|
+
* or checks. Its `url` follows `number`.
|
|
160
|
+
*/
|
|
161
|
+
export declare function prRow(overrides?: RowOverrides<GhPrJson>): GhPrJson;
|
|
162
|
+
/** An issue as `gh issue list`/`view --json number,title,body,labels,state` prints it. */
|
|
163
|
+
export interface GhIssueJson {
|
|
164
|
+
/** Required: a row without a numeric `number` is dropped. */
|
|
165
|
+
number: number;
|
|
166
|
+
title: string;
|
|
167
|
+
body: string;
|
|
168
|
+
labels: GhLabelJson[];
|
|
169
|
+
/** `OPEN` or `CLOSED`. */
|
|
170
|
+
state: string;
|
|
171
|
+
}
|
|
172
|
+
/** An open issue #1 with no labels. */
|
|
173
|
+
export declare function issueRow(overrides?: RowOverrides<GhIssueJson>): GhIssueJson;
|
|
174
|
+
/** A repository as `gh repo list`/`view --json` prints it, with every field the parser reads. */
|
|
175
|
+
export interface GhRepoJson {
|
|
176
|
+
/** Required: `owner/name`, both parts non-empty, or the row is dropped. */
|
|
177
|
+
nameWithOwner: string;
|
|
178
|
+
description: string;
|
|
179
|
+
/** `{ name: '' }` for an empty repository, as gh prints it. `null` parses the same. */
|
|
180
|
+
defaultBranchRef: {
|
|
181
|
+
name: string;
|
|
182
|
+
} | null;
|
|
183
|
+
visibility: RepositoryVisibility;
|
|
184
|
+
isArchived: boolean;
|
|
185
|
+
url: string;
|
|
186
|
+
}
|
|
187
|
+
/** The public, unarchived `octo-org/hello-world` on `main`. Its `url` follows `nameWithOwner`. */
|
|
188
|
+
export declare function repoRow(overrides?: RowOverrides<GhRepoJson>): GhRepoJson;
|
|
189
|
+
/** A row of `gh search prs --json`, with every field the parser reads. */
|
|
190
|
+
export interface GhSearchPrJson {
|
|
191
|
+
/** Required: a row without a numeric `number` is dropped. */
|
|
192
|
+
number: number;
|
|
193
|
+
title: string;
|
|
194
|
+
/** Search answers in lower case: `open`, `closed` or `merged`. */
|
|
195
|
+
state: string;
|
|
196
|
+
url: string;
|
|
197
|
+
isDraft: boolean;
|
|
198
|
+
repository: {
|
|
199
|
+
name: string;
|
|
200
|
+
nameWithOwner: string;
|
|
201
|
+
};
|
|
202
|
+
author: GhActorJson | null;
|
|
203
|
+
labels: GhLabelJson[];
|
|
204
|
+
createdAt: string;
|
|
205
|
+
updatedAt: string;
|
|
206
|
+
/**
|
|
207
|
+
* gh prints `0001-01-01T00:00:00Z`, Go's zero time, for a hit that is not
|
|
208
|
+
* closed. The parser reads that as `null`.
|
|
209
|
+
*/
|
|
210
|
+
closedAt: string | null;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* An open pull request #1 in `octo-org/hello-world`, as search returns it. Its
|
|
214
|
+
* `url` follows `number` and `repository`.
|
|
215
|
+
*/
|
|
216
|
+
export declare function searchPrRow(overrides?: RowOverrides<GhSearchPrJson>): GhSearchPrJson;
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@osdlc/typed-gh/testing`: rows of `gh --json` output, for faking `gh` in
|
|
3
|
+
* tests.
|
|
4
|
+
*
|
|
5
|
+
* A separate subpath, not part of the package entry, so production code does
|
|
6
|
+
* not carry fixture data. Nothing in `src/` but this file knows about it.
|
|
7
|
+
*
|
|
8
|
+
* Each builder returns gh's raw JSON shape, what `gh … --json` prints
|
|
9
|
+
* (`nameWithOwner`, `headRefName`, `defaultBranchRef: { name }`), not the
|
|
10
|
+
* parsed model. Feed the rows to a fake runner through {@link ghResult} and
|
|
11
|
+
* the real parsers read them, so a test exercises the same parsing a real
|
|
12
|
+
* `gh` call does.
|
|
13
|
+
*
|
|
14
|
+
* The defaults fill every field the parsers require, which is where hand-made
|
|
15
|
+
* rows go wrong: a row the parser rejects is dropped without an error.
|
|
16
|
+
*
|
|
17
|
+
* - A pull request needs an integer `number` (`parsePullRequest`), and
|
|
18
|
+
* `prList({ head })` also keeps only rows whose `headRefName` equals
|
|
19
|
+
* `head`.
|
|
20
|
+
* - An issue and a search hit need a numeric `number`.
|
|
21
|
+
* - A repository needs `nameWithOwner` as `owner/name`, both parts
|
|
22
|
+
* non-empty (`parseRepository`).
|
|
23
|
+
* - A label needs a non-empty `name` (`parseLabels`).
|
|
24
|
+
* - A check needs a `name`, or a `context` for a legacy status context
|
|
25
|
+
* (`parseCheckRun`).
|
|
26
|
+
*
|
|
27
|
+
* Overrides merge shallowly: a field you pass replaces the default whole, and
|
|
28
|
+
* a field you pass as `undefined` is left out of the row, to test a payload
|
|
29
|
+
* that lacks it. A default that names another field (a pull request's `url`
|
|
30
|
+
* names its `number`) follows your override of that field. The default
|
|
31
|
+
* values may change in a minor release, as long as every parser still
|
|
32
|
+
* accepts them, so assert on what you set, not on a default.
|
|
33
|
+
*/
|
|
34
|
+
/** `defaults` with `overrides` merged over them. An `undefined` override drops the field. */
|
|
35
|
+
function build(defaults, overrides) {
|
|
36
|
+
const row = { ...defaults };
|
|
37
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
38
|
+
if (value === undefined)
|
|
39
|
+
delete row[key];
|
|
40
|
+
else
|
|
41
|
+
row[key] = value;
|
|
42
|
+
}
|
|
43
|
+
return row;
|
|
44
|
+
}
|
|
45
|
+
const HOST = 'https://github.com';
|
|
46
|
+
const REPO = 'octo-org/hello-world';
|
|
47
|
+
const CREATED_AT = '2024-01-15T09:30:00Z';
|
|
48
|
+
const UPDATED_AT = '2024-01-16T14:05:00Z';
|
|
49
|
+
const HEAD_OID = '6dcb09b5b57875f334f61aebed695e2e4193db5e';
|
|
50
|
+
// ── the result ──────────────────────────────────────────────────────────────
|
|
51
|
+
/**
|
|
52
|
+
* A successful `gh` call that printed `payload` as JSON: exit code 0, the
|
|
53
|
+
* payload on stdout with gh's trailing newline, and nothing on stderr. Pass an
|
|
54
|
+
* array of rows for a list verb and one row for a view verb.
|
|
55
|
+
*/
|
|
56
|
+
export function ghResult(payload) {
|
|
57
|
+
return { exitCode: 0, stdout: `${JSON.stringify(payload)}\n`, stderr: '' };
|
|
58
|
+
}
|
|
59
|
+
/** A new object each call, so a test that edits one row's author edits only that row. */
|
|
60
|
+
function octocat() {
|
|
61
|
+
return { id: 'MDQ6VXNlcjU4MzIzMQ==', is_bot: false, login: 'octocat', name: 'The Octocat' };
|
|
62
|
+
}
|
|
63
|
+
/** A label row. The default is GitHub's own `bug` label. */
|
|
64
|
+
export function labelRow(overrides = {}) {
|
|
65
|
+
return build({ name: 'bug', color: 'd73a4a', description: "Something isn't working" }, overrides);
|
|
66
|
+
}
|
|
67
|
+
/** A check run. The default completed with `SUCCESS`, so it reads as a green check. */
|
|
68
|
+
export function checkRunRow(overrides = {}) {
|
|
69
|
+
return build({
|
|
70
|
+
__typename: 'CheckRun',
|
|
71
|
+
name: 'test',
|
|
72
|
+
workflowName: 'CI',
|
|
73
|
+
status: 'COMPLETED',
|
|
74
|
+
conclusion: 'SUCCESS',
|
|
75
|
+
detailsUrl: `${HOST}/${REPO}/actions/runs/1/job/1`,
|
|
76
|
+
startedAt: CREATED_AT,
|
|
77
|
+
completedAt: UPDATED_AT,
|
|
78
|
+
}, overrides);
|
|
79
|
+
}
|
|
80
|
+
/** A legacy status context. The default is a `SUCCESS`. */
|
|
81
|
+
export function statusContextRow(overrides = {}) {
|
|
82
|
+
return build({
|
|
83
|
+
__typename: 'StatusContext',
|
|
84
|
+
context: 'ci/build',
|
|
85
|
+
state: 'SUCCESS',
|
|
86
|
+
targetUrl: 'https://ci.example.com/builds/1',
|
|
87
|
+
startedAt: CREATED_AT,
|
|
88
|
+
}, overrides);
|
|
89
|
+
}
|
|
90
|
+
/** A comment by `octocat`. */
|
|
91
|
+
export function commentRow(overrides = {}) {
|
|
92
|
+
return build({
|
|
93
|
+
id: 'IC_kwDOAbCdEf5xYz12',
|
|
94
|
+
author: { login: 'octocat' },
|
|
95
|
+
authorAssociation: 'MEMBER',
|
|
96
|
+
body: 'Looks good to me.',
|
|
97
|
+
createdAt: UPDATED_AT,
|
|
98
|
+
url: `${HOST}/${REPO}/pull/1#issuecomment-1`,
|
|
99
|
+
}, overrides);
|
|
100
|
+
}
|
|
101
|
+
/** An approving review by `octocat`. */
|
|
102
|
+
export function reviewRow(overrides = {}) {
|
|
103
|
+
return build({
|
|
104
|
+
id: 'PRR_kwDOAbCdEf5xYz34',
|
|
105
|
+
author: { login: 'octocat' },
|
|
106
|
+
authorAssociation: 'MEMBER',
|
|
107
|
+
body: '',
|
|
108
|
+
state: 'APPROVED',
|
|
109
|
+
submittedAt: UPDATED_AT,
|
|
110
|
+
commit: { oid: HEAD_OID },
|
|
111
|
+
}, overrides);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* An open, mergeable pull request #1 from `feature/add-retries` into `main`
|
|
115
|
+
* of `octo-org/hello-world`, by `octocat`, with no labels, comments, reviews
|
|
116
|
+
* or checks. Its `url` follows `number`.
|
|
117
|
+
*/
|
|
118
|
+
export function prRow(overrides = {}) {
|
|
119
|
+
const number = overrides.number ?? 1;
|
|
120
|
+
return build({
|
|
121
|
+
number,
|
|
122
|
+
state: 'OPEN',
|
|
123
|
+
title: 'Add retries to the fetch loop',
|
|
124
|
+
body: 'Retries a failed fetch three times before giving up.',
|
|
125
|
+
url: `${HOST}/${REPO}/pull/${number}`,
|
|
126
|
+
isDraft: false,
|
|
127
|
+
baseRefName: 'main',
|
|
128
|
+
headRefName: 'feature/add-retries',
|
|
129
|
+
headRefOid: HEAD_OID,
|
|
130
|
+
isCrossRepository: false,
|
|
131
|
+
mergeable: 'MERGEABLE',
|
|
132
|
+
mergeStateStatus: 'CLEAN',
|
|
133
|
+
reviewDecision: '',
|
|
134
|
+
author: octocat(),
|
|
135
|
+
labels: [],
|
|
136
|
+
comments: [],
|
|
137
|
+
reviews: [],
|
|
138
|
+
statusCheckRollup: [],
|
|
139
|
+
mergedAt: null,
|
|
140
|
+
createdAt: CREATED_AT,
|
|
141
|
+
updatedAt: UPDATED_AT,
|
|
142
|
+
}, overrides);
|
|
143
|
+
}
|
|
144
|
+
/** An open issue #1 with no labels. */
|
|
145
|
+
export function issueRow(overrides = {}) {
|
|
146
|
+
return build({
|
|
147
|
+
number: 1,
|
|
148
|
+
title: 'Fetch gives up after one failure',
|
|
149
|
+
body: 'A single network error ends the whole sync.',
|
|
150
|
+
labels: [],
|
|
151
|
+
state: 'OPEN',
|
|
152
|
+
}, overrides);
|
|
153
|
+
}
|
|
154
|
+
/** The public, unarchived `octo-org/hello-world` on `main`. Its `url` follows `nameWithOwner`. */
|
|
155
|
+
export function repoRow(overrides = {}) {
|
|
156
|
+
const nameWithOwner = overrides.nameWithOwner ?? REPO;
|
|
157
|
+
return build({
|
|
158
|
+
nameWithOwner,
|
|
159
|
+
description: 'My first repository on GitHub.',
|
|
160
|
+
defaultBranchRef: { name: 'main' },
|
|
161
|
+
visibility: 'PUBLIC',
|
|
162
|
+
isArchived: false,
|
|
163
|
+
url: `${HOST}/${nameWithOwner}`,
|
|
164
|
+
}, overrides);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* An open pull request #1 in `octo-org/hello-world`, as search returns it. Its
|
|
168
|
+
* `url` follows `number` and `repository`.
|
|
169
|
+
*/
|
|
170
|
+
export function searchPrRow(overrides = {}) {
|
|
171
|
+
const number = overrides.number ?? 1;
|
|
172
|
+
const repository = overrides.repository ?? { name: 'hello-world', nameWithOwner: REPO };
|
|
173
|
+
return build({
|
|
174
|
+
number,
|
|
175
|
+
title: 'Add retries to the fetch loop',
|
|
176
|
+
state: 'open',
|
|
177
|
+
url: `${HOST}/${repository.nameWithOwner}/pull/${number}`,
|
|
178
|
+
isDraft: false,
|
|
179
|
+
repository,
|
|
180
|
+
author: { id: 'MDQ6VXNlcjU4MzIzMQ==', is_bot: false, login: 'octocat' },
|
|
181
|
+
labels: [],
|
|
182
|
+
createdAt: CREATED_AT,
|
|
183
|
+
updatedAt: UPDATED_AT,
|
|
184
|
+
closedAt: '0001-01-01T00:00:00Z',
|
|
185
|
+
}, overrides);
|
|
186
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@osdlc/typed-gh",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "A typed GitHub client for TypeScript over the gh CLI. A total PullRequest/Review/CheckRun model, pure argv builders and parsers, and a tri-modal client — queries return parsed values, mutations throw, raw() is the escape hatch. Uses gh's own credentials; reads no token.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"author": "sksizer",
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./testing": {
|
|
15
|
+
"types": "./dist/testing.d.ts",
|
|
16
|
+
"default": "./dist/testing.js"
|
|
13
17
|
}
|
|
14
18
|
},
|
|
15
19
|
"files": [
|
|
@@ -23,7 +27,7 @@
|
|
|
23
27
|
],
|
|
24
28
|
"dependencies": {
|
|
25
29
|
"@osdlc/command-seam": "^0.14.0",
|
|
26
|
-
"@osdlc/typed-git": "^0.
|
|
30
|
+
"@osdlc/typed-git": "^0.11.1",
|
|
27
31
|
"@osdlc/result": "^0.1.0"
|
|
28
32
|
},
|
|
29
33
|
"engines": {
|