@effected/github 0.16.0 → 0.18.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.
@@ -0,0 +1,183 @@
1
+ import { GitHubError } from "./GitHubError.js";
2
+ import { GitHubClient } from "./GitHubClient.js";
3
+ import { numericId } from "./internal/ids.js";
4
+ import { Context, Effect, Layer, Schema, Stream } from "effect";
5
+
6
+ //#region src/AuthenticatedApp.ts
7
+ /**
8
+ * The GitHub App itself, as `GET /app` reports it.
9
+ *
10
+ * @public
11
+ */
12
+ var AppInfo = class extends Schema.Class("AppInfo")({
13
+ /** The app's numeric id. */
14
+ id: Schema.Int,
15
+ /**
16
+ * The URL slug, e.g. `"my-app"`; the app's bot user is `<slug>[bot]`.
17
+ *
18
+ * @remarks
19
+ * Optional because GitHub's schema for an app declares it optional; the
20
+ * authenticated app's own read is where you would expect it.
21
+ */
22
+ slug: Schema.optionalKey(Schema.String),
23
+ /** The display name. */
24
+ name: Schema.String,
25
+ /** The app's GraphQL node id (wire `node_id`). */
26
+ nodeId: Schema.String,
27
+ /** The app's OAuth client id (wire `client_id`), when GitHub reports one. */
28
+ clientId: Schema.optionalKey(Schema.String),
29
+ /** The app's page on GitHub (wire `html_url`). */
30
+ htmlUrl: Schema.String
31
+ }) {};
32
+ /**
33
+ * One delivery of the app's webhook, as `GET /app/hook/deliveries` lists it.
34
+ *
35
+ * @remarks
36
+ * **Ids are numbers, and refuse to lose precision.** GitHub types a delivery
37
+ * id (and an installation or repository id) as int64, and octokit as
38
+ * `number | bigint`. A response body arrives through `JSON.parse`, which
39
+ * never produces a bigint: an id beyond 2^53 would already have been rounded.
40
+ * Every id here is decoded as a **safe** integer, so such an id fails the read
41
+ * with a typed `decode` error instead of handing back a rounded id that names
42
+ * a different delivery. Today's ids are many orders of magnitude below that
43
+ * line.
44
+ *
45
+ * Encodable: every field is a JSON primitive, so a delivery can be stored as
46
+ * it is.
47
+ *
48
+ * @public
49
+ */
50
+ var DeliveryAttempt = class extends Schema.Class("DeliveryAttempt")({
51
+ /** The delivery's id; pass it to {@link AuthenticatedAppShape.redeliver}. */
52
+ id: Schema.Int,
53
+ /**
54
+ * The event's GUID (the `X-GitHub-Delivery` header). Shared by a delivery
55
+ * and all its redeliveries, so it identifies the event; `id` identifies
56
+ * the attempt.
57
+ */
58
+ guid: Schema.String,
59
+ /** When it was delivered, as GitHub's ISO 8601 string (wire `delivered_at`). */
60
+ deliveredAt: Schema.String,
61
+ /** Whether this attempt was a redelivery. */
62
+ redelivery: Schema.Boolean,
63
+ /** How long the delivery took, in seconds. */
64
+ duration: Schema.Number,
65
+ /** GitHub's description of the outcome, e.g. `"OK"`. */
66
+ status: Schema.String,
67
+ /** The HTTP status your endpoint answered (wire `status_code`); `0` when it never answered. */
68
+ statusCode: Schema.Int,
69
+ /** The event, e.g. `"workflow_run"`. */
70
+ event: Schema.String,
71
+ /** The event's action, e.g. `"completed"`; `null` for an event without one. */
72
+ action: Schema.NullOr(Schema.String),
73
+ /** The installation the event concerns (wire `installation_id`); `null` for none. */
74
+ installationId: Schema.NullOr(Schema.Int),
75
+ /** The repository the event concerns (wire `repository_id`); `null` for none. */
76
+ repositoryId: Schema.NullOr(Schema.Int),
77
+ /** When the delivery was throttled (wire `throttled_at`), when GitHub reports it. */
78
+ throttledAt: Schema.optionalKey(Schema.NullOr(Schema.String))
79
+ }) {};
80
+ /**
81
+ * The app-level REST surface: the app's own record, its webhook delivery log
82
+ * and redelivery, and uninstalling.
83
+ *
84
+ * @remarks
85
+ * Provide {@link AuthenticatedApp.layer} over an App-JWT client from
86
+ * {@link GitHubApp.appClientLayer}. This module imports no JWT signer: the
87
+ * credential is the client's business, so a test drives it with any client.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * import { AuthenticatedApp, GitHubApp } from "@effected/github";
92
+ * import { DateTime, Effect, Layer, Redacted, Stream } from "effect";
93
+ *
94
+ * // Redeliver every failed delivery from the last hour.
95
+ * const sweep = Effect.gen(function* () {
96
+ * const app = yield* AuthenticatedApp;
97
+ * const since = DateTime.subtract(yield* DateTime.now, { hours: 1 });
98
+ * yield* app.deliveries({ status: "failure" }).pipe(
99
+ * Stream.takeWhile((delivery) => DateTime.isGreaterThan(DateTime.makeUnsafe(delivery.deliveredAt), since)),
100
+ * Stream.runForEach((delivery) => app.redeliver(delivery.id)),
101
+ * );
102
+ * });
103
+ *
104
+ * const layer = AuthenticatedApp.layer.pipe(
105
+ * Layer.provide(
106
+ * GitHubApp.appClientLayer({
107
+ * appId: "12345",
108
+ * privateKey: Redacted.make("-----BEGIN RSA PRIVATE KEY-----\n..."),
109
+ * }),
110
+ * ),
111
+ * );
112
+ *
113
+ * Effect.runPromise(Effect.provide(sweep, layer));
114
+ * ```
115
+ *
116
+ * @public
117
+ */
118
+ var AuthenticatedApp = class AuthenticatedApp extends Context.Service()("@effected/github/AuthenticatedApp") {
119
+ /** The live service, built over an App-JWT `GitHubClient`. */
120
+ static layer = Layer.effect(this, Effect.map(GitHubClient, (client) => make(client)));
121
+ /** An in-memory double; unstubbed members die naming themselves. */
122
+ static makeTest = (overrides = {}) => ({
123
+ get: overrides.get ?? (() => unstubbed("get")),
124
+ deliveries: overrides.deliveries ?? (() => unstubbed("deliveries")),
125
+ delivery: overrides.delivery ?? (() => unstubbed("delivery")),
126
+ redeliver: overrides.redeliver ?? (() => unstubbed("redeliver")),
127
+ uninstall: overrides.uninstall ?? (() => unstubbed("uninstall"))
128
+ });
129
+ /** {@link AuthenticatedApp.makeTest} behind a `Layer`. */
130
+ static layerTest = (overrides = {}) => Layer.succeed(AuthenticatedApp, AuthenticatedApp.makeTest(overrides));
131
+ };
132
+ const unstubbed = (member) => {
133
+ throw new Error(`AuthenticatedApp.makeTest: ${member}() was called but not stubbed — pass an override.`);
134
+ };
135
+ const decodeDelivery = Schema.decodeUnknownEffect(DeliveryAttempt);
136
+ const decodeApp = Schema.decodeUnknownEffect(AppInfo);
137
+ /** A nullable int64 id, narrowed like every other id. */
138
+ const nullableId = (id) => id === null ? null : numericId(id);
139
+ const deliveryOf = (operation, raw) => decodeDelivery(typeof raw !== "object" || raw === null ? raw : {
140
+ id: numericId(raw.id),
141
+ guid: raw.guid,
142
+ deliveredAt: raw.delivered_at,
143
+ redelivery: raw.redelivery,
144
+ duration: raw.duration,
145
+ status: raw.status,
146
+ statusCode: raw.status_code,
147
+ event: raw.event,
148
+ action: raw.action,
149
+ installationId: nullableId(raw.installation_id),
150
+ repositoryId: nullableId(raw.repository_id),
151
+ ...raw.throttled_at !== void 0 ? { throttledAt: raw.throttled_at } : {}
152
+ }).pipe(Effect.catchTag("SchemaError", (error) => Effect.fail(GitHubError.decode(operation, "GitHub returned an unexpected webhook delivery", error))));
153
+ const make = (client) => ({
154
+ get: Effect.fn("AuthenticatedApp.get")(function* () {
155
+ const app = yield* client.request("GET /app", {});
156
+ if (app === null) return yield* GitHubError.decode("AuthenticatedApp.get", "GET /app returned no app");
157
+ return yield* decodeApp({
158
+ id: numericId(app.id),
159
+ ...app.slug !== void 0 ? { slug: app.slug } : {},
160
+ name: app.name,
161
+ nodeId: app.node_id,
162
+ ...app.client_id !== void 0 ? { clientId: app.client_id } : {},
163
+ htmlUrl: app.html_url
164
+ }).pipe(Effect.catchTag("SchemaError", (error) => Effect.fail(GitHubError.decode("AuthenticatedApp.get", "GitHub returned an unexpected app", error))));
165
+ }),
166
+ deliveries: (options) => client.paginateStream("GET /app/hook/deliveries", options?.status !== void 0 ? { status: options.status } : {}, options?.page).pipe(Stream.mapEffect((raw) => deliveryOf("AuthenticatedApp.deliveries", raw))),
167
+ delivery: Effect.fn("AuthenticatedApp.delivery")(function* (deliveryId) {
168
+ yield* Effect.annotateCurrentSpan({ deliveryId });
169
+ const raw = yield* client.request("GET /app/hook/deliveries/{delivery_id}", { delivery_id: deliveryId });
170
+ return yield* deliveryOf("AuthenticatedApp.delivery", raw);
171
+ }),
172
+ redeliver: Effect.fn("AuthenticatedApp.redeliver")(function* (deliveryId) {
173
+ yield* Effect.annotateCurrentSpan({ deliveryId });
174
+ yield* client.request("POST /app/hook/deliveries/{delivery_id}/attempts", { delivery_id: deliveryId });
175
+ }),
176
+ uninstall: Effect.fn("AuthenticatedApp.uninstall")(function* (installationId) {
177
+ yield* Effect.annotateCurrentSpan({ installationId });
178
+ yield* client.request("DELETE /app/installations/{installation_id}", { installation_id: installationId });
179
+ })
180
+ });
181
+
182
+ //#endregion
183
+ export { AppInfo, AuthenticatedApp, DeliveryAttempt };
package/CheckRun.js CHANGED
@@ -15,6 +15,48 @@ const CheckConclusion = Schema.Literals([
15
15
  "action_required",
16
16
  "skipped"
17
17
  ]);
18
+ /**
19
+ * The phase of its lifecycle a check run is in, as GitHub reports it.
20
+ *
21
+ * @remarks
22
+ * `"waiting"`, `"requested"` and `"pending"` are reserved for GitHub Actions
23
+ * runs; an integrator can only write `"queued"`, `"in_progress"` and, through
24
+ * {@link CheckRunShape.complete}, `"completed"`.
25
+ *
26
+ * @public
27
+ */
28
+ const CheckRunStatus = Schema.Literals([
29
+ "queued",
30
+ "in_progress",
31
+ "completed",
32
+ "waiting",
33
+ "requested",
34
+ "pending"
35
+ ]);
36
+ /**
37
+ * How a check run finished, as GitHub reports it: every
38
+ * {@link CheckConclusion} plus `"stale"`.
39
+ *
40
+ * @remarks
41
+ * GitHub's check-run response schema omits `"stale"`, but its update
42
+ * endpoint documents it: *"You cannot change a check run conclusion to
43
+ * `stale`, only GitHub can set this."* GitHub sets it on a run left
44
+ * incomplete too long, so a read that refused it would fail on any commit
45
+ * carrying one. It is read-only, which is why {@link CheckConclusion}, the
46
+ * write set, does not include it.
47
+ *
48
+ * @public
49
+ */
50
+ const ReportedCheckConclusion = Schema.Literals([
51
+ "success",
52
+ "failure",
53
+ "neutral",
54
+ "cancelled",
55
+ "timed_out",
56
+ "action_required",
57
+ "skipped",
58
+ "stale"
59
+ ]);
18
60
  /** How serious an annotation is. @public */
19
61
  const AnnotationLevel = Schema.Literals([
20
62
  "notice",
@@ -113,22 +155,76 @@ const capBytes = (value) => {
113
155
  return `${cut}${CheckRunOutput.NOTICE}`;
114
156
  };
115
157
  /**
158
+ * The rendered output a check run reports: its title and summary, and how
159
+ * many annotations it carries.
160
+ *
161
+ * @remarks
162
+ * The read-side counterpart of {@link CheckRunOutput}. It leaves out the
163
+ * long-form `text` deliberately: it can run to 65535 bytes, and a caller
164
+ * listing a commit's runs rarely wants it. Read the run's full output through
165
+ * the typed request surface when you do.
166
+ *
167
+ * @public
168
+ */
169
+ var ReportedCheckRunOutput = class extends Schema.Class("ReportedCheckRunOutput")({
170
+ /** The output's title; `null` when the run has none. */
171
+ title: Schema.NullOr(Schema.String),
172
+ /** The output's markdown summary; `null` when the run has none. */
173
+ summary: Schema.NullOr(Schema.String),
174
+ /** How many annotations the run carries (wire `annotations_count`). */
175
+ annotationsCount: Schema.Int
176
+ }) {};
177
+ /**
116
178
  * A check run as GitHub reports it.
117
179
  *
180
+ * @remarks
181
+ * Every field beyond the original five (the four required ones and
182
+ * `externalId`) is optional, so a test double built with
183
+ * `CheckRunRef.make({ id, name, url, status })` stays valid; a run decoded
184
+ * from a GitHub response carries all of them, because GitHub always sends
185
+ * them. A nullable field is `null` when GitHub reported `null`.
186
+ *
187
+ * **Three URLs, named apart.** `url` is the **web** URL (wire `html_url`, or
188
+ * `""` when GitHub reported none), kept under that name so existing callers
189
+ * read what they always read. `htmlUrl` is the same wire field with its
190
+ * `null` preserved, `apiUrl` is the REST URL (wire `url`), and `detailsUrl`
191
+ * is the integrator's own link (wire `details_url`).
192
+ *
118
193
  * @public
119
194
  */
120
195
  var CheckRunRef = class extends Schema.Class("CheckRunRef")({
121
196
  id: Schema.Int,
122
197
  name: Schema.String,
123
- /** The web URL. */
198
+ /** The web URL (wire `html_url`), or `""` when GitHub reported none. See also `htmlUrl`. */
124
199
  url: Schema.String,
125
- status: Schema.String,
200
+ /** The run's lifecycle phase. */
201
+ status: CheckRunStatus,
126
202
  /**
127
203
  * The integrator's own id for the run (wire `external_id`), when it has
128
204
  * one. GitHub reports a run created without one as `null` or `""`; both
129
205
  * leave this absent.
130
206
  */
131
- externalId: Schema.optionalKey(Schema.String)
207
+ externalId: Schema.optionalKey(Schema.String),
208
+ /** The commit the run checks (wire `head_sha`). */
209
+ headSha: Schema.optionalKey(Schema.String),
210
+ /** The run's GraphQL node id (wire `node_id`). */
211
+ nodeId: Schema.optionalKey(Schema.String),
212
+ /** How the run finished; `null` until it completes. */
213
+ conclusion: Schema.optionalKey(Schema.NullOr(ReportedCheckConclusion)),
214
+ /** When the run started, as GitHub's ISO 8601 string; `null` for a run that has not. */
215
+ startedAt: Schema.optionalKey(Schema.NullOr(Schema.String)),
216
+ /** When the run completed, as GitHub's ISO 8601 string; `null` for a run that has not. */
217
+ completedAt: Schema.optionalKey(Schema.NullOr(Schema.String)),
218
+ /** The integrator's link for the run (wire `details_url`). */
219
+ detailsUrl: Schema.optionalKey(Schema.NullOr(Schema.String)),
220
+ /** The web URL (wire `html_url`), `null` preserved. */
221
+ htmlUrl: Schema.optionalKey(Schema.NullOr(Schema.String)),
222
+ /** The run's REST API URL (wire `url`). */
223
+ apiUrl: Schema.optionalKey(Schema.String),
224
+ /** The check suite the run belongs to (wire `check_suite.id`); `null` when GitHub reported none. */
225
+ checkSuiteId: Schema.optionalKey(Schema.NullOr(Schema.Int)),
226
+ /** The run's title, summary and annotation count. */
227
+ output: Schema.optionalKey(ReportedCheckRunOutput)
132
228
  }) {};
133
229
  /**
134
230
  * Create, update and conclude GitHub check runs, including the
@@ -148,8 +244,11 @@ var CheckRun = class CheckRun extends Context.Service()("@effected/github/CheckR
148
244
  create: overrides.create ?? (() => unstubbed("create")),
149
245
  get: overrides.get ?? (() => unstubbed("get")),
150
246
  update: overrides.update ?? (() => unstubbed("update")),
247
+ updateRef: overrides.updateRef ?? (() => unstubbed("updateRef")),
248
+ list: overrides.list ?? (() => unstubbed("list")),
151
249
  findByExternalId: overrides.findByExternalId ?? (() => unstubbed("findByExternalId")),
152
250
  complete: overrides.complete ?? (() => unstubbed("complete")),
251
+ completeRef: overrides.completeRef ?? (() => unstubbed("completeRef")),
153
252
  withCheckRun: overrides.withCheckRun ?? (() => unstubbed("withCheckRun"))
154
253
  });
155
254
  /** {@link CheckRun.makeTest} behind a `Layer`. */
@@ -226,6 +325,19 @@ const concludeFor = (name, id, exit, recorded, complete) => {
226
325
  return Exit.isSuccess(exit) ? write : Effect.ignore(write);
227
326
  };
228
327
  const decodeRef = Schema.decodeUnknownEffect(CheckRunRef);
328
+ /** Whether a wire value is an object whose fields can be read. */
329
+ const isRecord = (value) => typeof value === "object" && value !== null;
330
+ /**
331
+ * A nested wire object's fields, renamed for the schema, or the value itself
332
+ * when it is not an object.
333
+ *
334
+ * @remarks
335
+ * Handing the raw value through is what keeps a malformed response typed: a
336
+ * `null` `output` (which GitHub's schema forbids) reaches the decoder and fails
337
+ * as `decode` instead of throwing a `TypeError` while its fields are read,
338
+ * which would be a defect escaping every `GitHubError` handler.
339
+ */
340
+ const nested = (value, project) => isRecord(value) ? project(value) : value;
229
341
  /**
230
342
  * Project a check-run response onto {@link CheckRunRef}, **decoding** it.
231
343
  *
@@ -233,14 +345,30 @@ const decodeRef = Schema.decodeUnknownEffect(CheckRunRef);
233
345
  * Decoded rather than built with `make`, which throws: a response missing a
234
346
  * field (a hand-written double, or GitHub changing shape) is input, and input
235
347
  * failures are a typed `decode` `GitHubError` naming the operation rather than
236
- * a defect.
348
+ * a defect. That includes a status or conclusion outside the literal sets:
349
+ * GitHub adding one fails the read loudly instead of passing an unknown
350
+ * string to a caller's exhaustive switch.
237
351
  */
238
- const refOf = (operation, raw) => decodeRef({
352
+ const refOf = (operation, raw) => decodeRef(!isRecord(raw) ? raw : {
239
353
  id: numericId(raw.id),
240
354
  name: raw.name,
241
355
  url: raw.html_url ?? "",
242
356
  status: raw.status,
243
- ...raw.external_id ? { externalId: raw.external_id } : {}
357
+ ...raw.external_id ? { externalId: raw.external_id } : {},
358
+ ...raw.head_sha !== void 0 ? { headSha: raw.head_sha } : {},
359
+ ...raw.node_id !== void 0 ? { nodeId: raw.node_id } : {},
360
+ ...raw.conclusion !== void 0 ? { conclusion: raw.conclusion } : {},
361
+ ...raw.started_at !== void 0 ? { startedAt: raw.started_at } : {},
362
+ ...raw.completed_at !== void 0 ? { completedAt: raw.completed_at } : {},
363
+ ...raw.details_url !== void 0 ? { detailsUrl: raw.details_url } : {},
364
+ ...raw.html_url !== void 0 ? { htmlUrl: raw.html_url } : {},
365
+ ...raw.url !== void 0 ? { apiUrl: raw.url } : {},
366
+ ...raw.check_suite !== void 0 ? { checkSuiteId: nested(raw.check_suite, (suite) => typeof suite.id === "number" || typeof suite.id === "bigint" ? numericId(suite.id) : suite.id) } : {},
367
+ ...raw.output !== void 0 ? { output: nested(raw.output, (output) => ({
368
+ title: output.title,
369
+ summary: output.summary,
370
+ annotationsCount: output.annotations_count
371
+ })) } : {}
244
372
  }).pipe(Effect.catchTag("SchemaError", (error) => Effect.fail(GitHubError.decode(operation, "GitHub returned an unexpected check run", error))));
245
373
  /** The current time as GitHub's ISO 8601 timestamp, from `Clock` so `TestClock` drives it. */
246
374
  const isoNow = Effect.map(DateTime.now, DateTime.formatIso);
@@ -267,7 +395,17 @@ const make = (client) => {
267
395
  });
268
396
  return yield* refOf("CheckRun.create", created);
269
397
  });
270
- const complete = Effect.fn("CheckRun.complete")(function* (id, conclusion, output, options) {
398
+ /**
399
+ * The completing PATCH, answering GitHub's raw response.
400
+ *
401
+ * @remarks
402
+ * Shared by `complete`, which discards the response, and `completeRef`,
403
+ * which decodes it. Only the second can fail on an unexpected response:
404
+ * `complete` runs inside the bracket's finalizer, and a run GitHub has
405
+ * already concluded must not fail the program over a field it did not ask
406
+ * to read.
407
+ */
408
+ const completePatch = (id, conclusion, output, options) => Effect.gen(function* () {
271
409
  const { owner, repo } = yield* Repo;
272
410
  yield* Effect.annotateCurrentSpan({
273
411
  owner,
@@ -275,7 +413,7 @@ const make = (client) => {
275
413
  id,
276
414
  conclusion
277
415
  });
278
- yield* client.request("PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}", {
416
+ return yield* client.request("PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}", {
279
417
  owner,
280
418
  repo,
281
419
  check_run_id: id,
@@ -286,6 +424,30 @@ const make = (client) => {
286
424
  ...options?.detailsUrl !== void 0 ? { details_url: options.detailsUrl } : {}
287
425
  });
288
426
  });
427
+ const complete = Effect.fn("CheckRun.complete")(function* (id, conclusion, output, options) {
428
+ yield* completePatch(id, conclusion, output, options);
429
+ });
430
+ const completeRef = Effect.fn("CheckRun.completeRef")(function* (id, conclusion, output, options) {
431
+ return yield* refOf("CheckRun.completeRef", yield* completePatch(id, conclusion, output, options));
432
+ });
433
+ /** The updating PATCH, answering GitHub's raw response; see `completePatch` for why it is shared. */
434
+ const updatePatch = (id, output, options) => Effect.gen(function* () {
435
+ const { owner, repo } = yield* Repo;
436
+ yield* Effect.annotateCurrentSpan({
437
+ owner,
438
+ repo,
439
+ id
440
+ });
441
+ return yield* client.request("PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}", {
442
+ owner,
443
+ repo,
444
+ check_run_id: id,
445
+ ...output !== void 0 ? { output: wireOutput(output) } : {},
446
+ ...options?.status !== void 0 ? { status: options.status } : {},
447
+ ...options?.status === "in_progress" ? { started_at: yield* isoNow } : {},
448
+ ...options?.detailsUrl !== void 0 ? { details_url: options.detailsUrl } : {}
449
+ });
450
+ });
289
451
  return {
290
452
  create,
291
453
  complete,
@@ -304,21 +466,29 @@ const make = (client) => {
304
466
  return yield* refOf("CheckRun.get", raw);
305
467
  }),
306
468
  update: Effect.fn("CheckRun.update")(function* (id, output, options) {
469
+ yield* updatePatch(id, output, options);
470
+ }),
471
+ updateRef: Effect.fn("CheckRun.updateRef")(function* (id, output, options) {
472
+ return yield* refOf("CheckRun.updateRef", yield* updatePatch(id, output, options));
473
+ }),
474
+ completeRef,
475
+ list: Effect.fn("CheckRun.list")(function* (ref, options) {
307
476
  const { owner, repo } = yield* Repo;
308
477
  yield* Effect.annotateCurrentSpan({
309
478
  owner,
310
479
  repo,
311
- id
480
+ ref
312
481
  });
313
- yield* client.request("PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}", {
482
+ const runs = yield* client.paginate("GET /repos/{owner}/{repo}/commits/{ref}/check-runs", {
314
483
  owner,
315
484
  repo,
316
- check_run_id: id,
317
- ...output !== void 0 ? { output: wireOutput(output) } : {},
485
+ ref,
486
+ ...options?.checkName !== void 0 ? { check_name: options.checkName } : {},
487
+ ...options?.appId !== void 0 ? { app_id: options.appId } : {},
318
488
  ...options?.status !== void 0 ? { status: options.status } : {},
319
- ...options?.status === "in_progress" ? { started_at: yield* isoNow } : {},
320
- ...options?.detailsUrl !== void 0 ? { details_url: options.detailsUrl } : {}
321
- });
489
+ ...options?.filter !== void 0 ? { filter: options.filter } : {}
490
+ }, options?.page);
491
+ return yield* Effect.forEach(runs, (run) => refOf("CheckRun.list", run));
322
492
  }),
323
493
  findByExternalId: Effect.fn("CheckRun.findByExternalId")(function* (headSha, name, externalId) {
324
494
  if (externalId === "") return Option.none();
@@ -357,4 +527,4 @@ const make = (client) => {
357
527
  };
358
528
 
359
529
  //#endregion
360
- export { Annotation, AnnotationLevel, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef };
530
+ export { Annotation, AnnotationLevel, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef, CheckRunStatus, ReportedCheckConclusion, ReportedCheckRunOutput };
package/GitHubApp.js CHANGED
@@ -163,6 +163,21 @@ var AppIdentity = class extends Schema.Class("AppIdentity")({
163
163
  });
164
164
  }
165
165
  };
166
+ /**
167
+ * An app's bot user: the account its installation tokens act as.
168
+ *
169
+ * @remarks
170
+ * `id` is what to compare against an actor id on an event, such as
171
+ * `workflow_run.triggering_actor.id`: a login can be renamed, an id cannot.
172
+ *
173
+ * @public
174
+ */
175
+ var BotUser = class extends Schema.Class("BotUser")({
176
+ /** The bot user's numeric id. */
177
+ id: Schema.Int,
178
+ /** The bot user's login, `<slug>[bot]`. */
179
+ login: Schema.String
180
+ }) {};
166
181
  /** `suspended_at` as GitHub sends it: an ISO string, or `null` while active. */
167
182
  const SuspendedAt = Schema.OptionFromNullOr(Schema.DateTimeUtcFromString);
168
183
  /**
@@ -417,6 +432,7 @@ var GitHubApp = class GitHubApp extends Context.Service()("@effected/github/GitH
417
432
  scopedToken: overrides.scopedToken ?? (() => unstubbed("scopedToken")),
418
433
  revoke: overrides.revoke ?? (() => unstubbed("revoke")),
419
434
  identity: overrides.identity ?? (() => unstubbed("identity")),
435
+ botUser: overrides.botUser ?? (() => unstubbed("botUser")),
420
436
  installations: overrides.installations ?? (() => unstubbed("installations"))
421
437
  });
422
438
  /** {@link GitHubApp.makeTest} behind a `Layer`. */
@@ -541,6 +557,15 @@ function makeApp(options) {
541
557
  ...Option.isSome(user) ? { userId: numericId(user.value.id) } : {}
542
558
  });
543
559
  }),
560
+ botUser: Effect.fn("GitHubApp.botUser")(function* (request) {
561
+ yield* Effect.annotateCurrentSpan({ slug: request.slug });
562
+ const user = yield* (yield* asBearer(request.installationToken, options)).request("GET /users/{username}", { username: `${request.slug}[bot]` }).pipe(Effect.catch(appFailure("identity")));
563
+ const raw = user;
564
+ return yield* Schema.decodeUnknownEffect(BotUser)(typeof raw === "object" && raw !== null ? {
565
+ id: numericId(user.id),
566
+ login: user.login
567
+ } : raw).pipe(Effect.catchTag("SchemaError", (error) => Effect.fail(GitHubAppError.of("identity", "GitHub returned an unexpected bot user", error))));
568
+ }),
544
569
  installations
545
570
  };
546
571
  });
@@ -614,4 +639,4 @@ const makeRotatingClient = (mint, release, options, operation) => Effect.gen(fun
614
639
  });
615
640
 
616
641
  //#endregion
617
- export { AppIdentity, BotIdentity, GitHubApp, GitHubAppError, Installation, InstallationToken };
642
+ export { AppIdentity, BotIdentity, BotUser, GitHubApp, GitHubAppError, Installation, InstallationToken };
@@ -26,6 +26,24 @@ var WorkflowRunStatus = class extends Schema.Class("WorkflowRunStatus")({
26
26
  return this.status === "completed";
27
27
  }
28
28
  };
29
+ /**
30
+ * The run a `workflow_dispatch` created, as GitHub reports it when asked.
31
+ *
32
+ * @remarks
33
+ * Returned by {@link WorkflowDispatchShape.dispatchWithRun}. `runId` is usable
34
+ * directly with {@link WorkflowDispatchShape.runStatus} and
35
+ * {@link WorkflowDispatchShape.cancelRun}.
36
+ *
37
+ * @public
38
+ */
39
+ var DispatchedRun = class extends Schema.Class("DispatchedRun")({
40
+ /** The created run's numeric id. */
41
+ runId: Schema.Int,
42
+ /** The run's API URL. */
43
+ runUrl: Schema.String,
44
+ /** The run's web URL. */
45
+ htmlUrl: Schema.String
46
+ }) {};
29
47
  const DEFAULT_INTERVAL = Duration.seconds(10);
30
48
  const DEFAULT_TIMEOUT = Duration.minutes(5);
31
49
  /**
@@ -60,6 +78,7 @@ var WorkflowDispatch = class WorkflowDispatch extends Context.Service()("@effect
60
78
  /** An in-memory double; unstubbed members die naming themselves. */
61
79
  static makeTest = (overrides = {}) => ({
62
80
  dispatch: overrides.dispatch ?? (() => unstubbed("dispatch")),
81
+ dispatchWithRun: overrides.dispatchWithRun ?? (() => unstubbed("dispatchWithRun")),
63
82
  runStatus: overrides.runStatus ?? (() => unstubbed("runStatus")),
64
83
  cancelRun: overrides.cancelRun ?? (() => unstubbed("cancelRun")),
65
84
  list: overrides.list ?? Effect.sync(() => unstubbed("list")),
@@ -77,6 +96,14 @@ const statusOf = (raw) => WorkflowRunStatus.make({
77
96
  ...raw.conclusion != null ? { conclusion: raw.conclusion } : {},
78
97
  url: raw.html_url
79
98
  });
99
+ /** GitHub's `workflow-dispatch-response`; the id is `number | bigint` in the generated types. */
100
+ const DispatchResponse = Schema.Struct({
101
+ workflow_run_id: Schema.Union([Schema.Number, Schema.BigInt]),
102
+ run_url: Schema.String,
103
+ html_url: Schema.String
104
+ });
105
+ const decodeDispatchResponse = Schema.decodeUnknownEffect(DispatchResponse);
106
+ const decodeDispatchedRun = Schema.decodeUnknownEffect(DispatchedRun);
80
107
  const make = (client) => {
81
108
  const dispatch = Effect.fn("WorkflowDispatch.dispatch")(function* (workflow, ref, inputs) {
82
109
  const { owner, repo } = yield* Repo;
@@ -94,6 +121,30 @@ const make = (client) => {
94
121
  ...inputs !== void 0 ? { inputs } : {}
95
122
  });
96
123
  });
124
+ const dispatchWithRun = Effect.fn("WorkflowDispatch.dispatchWithRun")(function* (workflow, ref, inputs) {
125
+ const { owner, repo } = yield* Repo;
126
+ yield* Effect.annotateCurrentSpan({
127
+ owner,
128
+ repo,
129
+ workflow,
130
+ ref
131
+ });
132
+ const data = yield* client.request("POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches", {
133
+ owner,
134
+ repo,
135
+ workflow_id: workflow,
136
+ ref,
137
+ ...inputs !== void 0 ? { inputs } : {},
138
+ return_run_details: true
139
+ });
140
+ if (data === "" || data === null) return Option.none();
141
+ const run = yield* decodeDispatchResponse(data).pipe(Effect.flatMap((raw) => decodeDispatchedRun({
142
+ runId: numericId(raw.workflow_run_id),
143
+ runUrl: raw.run_url,
144
+ htmlUrl: raw.html_url
145
+ })), Effect.catchTag("SchemaError", (error) => Effect.fail(GitHubError.decode("WorkflowDispatch.dispatchWithRun", "GitHub returned unexpected run details", error))));
146
+ return Option.some(run);
147
+ });
97
148
  const runStatus = Effect.fn("WorkflowDispatch.runStatus")(function* (runId) {
98
149
  const { owner, repo } = yield* Repo;
99
150
  yield* Effect.annotateCurrentSpan({
@@ -126,6 +177,7 @@ const make = (client) => {
126
177
  });
127
178
  return {
128
179
  dispatch,
180
+ dispatchWithRun,
129
181
  runStatus,
130
182
  cancelRun: Effect.fn("WorkflowDispatch.cancelRun")(function* (runId) {
131
183
  const { owner, repo } = yield* Repo;
@@ -154,8 +206,8 @@ const make = (client) => {
154
206
  attempts
155
207
  });
156
208
  const dispatchedAt = new Date(yield* Clock.currentTimeMillis).toISOString();
157
- yield* dispatch(workflow, ref, options?.inputs);
158
- const findRun = Effect.gen(function* () {
209
+ const dispatched = yield* dispatchWithRun(workflow, ref, options?.inputs);
210
+ const findRun = Option.isSome(dispatched) ? Effect.map(runStatus(dispatched.value.runId), Option.some) : Effect.gen(function* () {
159
211
  const match = (yield* client.paginate("GET /repos/{owner}/{repo}/actions/runs", {
160
212
  owner,
161
213
  repo,
@@ -179,4 +231,4 @@ const make = (client) => {
179
231
  };
180
232
 
181
233
  //#endregion
182
- export { WorkflowDispatch, WorkflowRunStatus };
234
+ export { DispatchedRun, WorkflowDispatch, WorkflowRunStatus };
package/index.d.ts CHANGED
@@ -1303,9 +1303,230 @@ export declare class Attestation extends Attestation_base {
1303
1303
  static readonly layerTest: (overrides?: Partial<AttestationShape>) => Layer.Layer<Attestation>;
1304
1304
  }
1305
1305
  //#endregion
1306
+ //#region src/AuthenticatedApp.d.ts
1307
+ declare const AppInfo_base: Schema.Class<AppInfo, Schema.Struct<{
1308
+ /** The app's numeric id. */
1309
+ readonly id: Schema.Int;
1310
+ /**
1311
+ * The URL slug, e.g. `"my-app"`; the app's bot user is `<slug>[bot]`.
1312
+ *
1313
+ * @remarks
1314
+ * Optional because GitHub's schema for an app declares it optional; the
1315
+ * authenticated app's own read is where you would expect it.
1316
+ */
1317
+ readonly slug: Schema.optionalKey<Schema.String>;
1318
+ /** The display name. */
1319
+ readonly name: Schema.String;
1320
+ /** The app's GraphQL node id (wire `node_id`). */
1321
+ readonly nodeId: Schema.String;
1322
+ /** The app's OAuth client id (wire `client_id`), when GitHub reports one. */
1323
+ readonly clientId: Schema.optionalKey<Schema.String>;
1324
+ /** The app's page on GitHub (wire `html_url`). */
1325
+ readonly htmlUrl: Schema.String;
1326
+ }>, {}>;
1327
+ /**
1328
+ * The GitHub App itself, as `GET /app` reports it.
1329
+ *
1330
+ * @public
1331
+ */
1332
+ export declare class AppInfo extends AppInfo_base {}
1333
+ declare const DeliveryAttempt_base: Schema.Class<DeliveryAttempt, Schema.Struct<{
1334
+ /** The delivery's id; pass it to {@link AuthenticatedAppShape.redeliver}. */
1335
+ readonly id: Schema.Int;
1336
+ /**
1337
+ * The event's GUID (the `X-GitHub-Delivery` header). Shared by a delivery
1338
+ * and all its redeliveries, so it identifies the event; `id` identifies
1339
+ * the attempt.
1340
+ */
1341
+ readonly guid: Schema.String;
1342
+ /** When it was delivered, as GitHub's ISO 8601 string (wire `delivered_at`). */
1343
+ readonly deliveredAt: Schema.String;
1344
+ /** Whether this attempt was a redelivery. */
1345
+ readonly redelivery: Schema.Boolean;
1346
+ /** How long the delivery took, in seconds. */
1347
+ readonly duration: Schema.Number;
1348
+ /** GitHub's description of the outcome, e.g. `"OK"`. */
1349
+ readonly status: Schema.String;
1350
+ /** The HTTP status your endpoint answered (wire `status_code`); `0` when it never answered. */
1351
+ readonly statusCode: Schema.Int;
1352
+ /** The event, e.g. `"workflow_run"`. */
1353
+ readonly event: Schema.String;
1354
+ /** The event's action, e.g. `"completed"`; `null` for an event without one. */
1355
+ readonly action: Schema.NullOr<Schema.String>;
1356
+ /** The installation the event concerns (wire `installation_id`); `null` for none. */
1357
+ readonly installationId: Schema.NullOr<Schema.Int>;
1358
+ /** The repository the event concerns (wire `repository_id`); `null` for none. */
1359
+ readonly repositoryId: Schema.NullOr<Schema.Int>;
1360
+ /** When the delivery was throttled (wire `throttled_at`), when GitHub reports it. */
1361
+ readonly throttledAt: Schema.optionalKey<Schema.NullOr<Schema.String>>;
1362
+ }>, {}>;
1363
+ /**
1364
+ * One delivery of the app's webhook, as `GET /app/hook/deliveries` lists it.
1365
+ *
1366
+ * @remarks
1367
+ * **Ids are numbers, and refuse to lose precision.** GitHub types a delivery
1368
+ * id (and an installation or repository id) as int64, and octokit as
1369
+ * `number | bigint`. A response body arrives through `JSON.parse`, which
1370
+ * never produces a bigint: an id beyond 2^53 would already have been rounded.
1371
+ * Every id here is decoded as a **safe** integer, so such an id fails the read
1372
+ * with a typed `decode` error instead of handing back a rounded id that names
1373
+ * a different delivery. Today's ids are many orders of magnitude below that
1374
+ * line.
1375
+ *
1376
+ * Encodable: every field is a JSON primitive, so a delivery can be stored as
1377
+ * it is.
1378
+ *
1379
+ * @public
1380
+ */
1381
+ export declare class DeliveryAttempt extends DeliveryAttempt_base {}
1382
+ /**
1383
+ * Options for {@link AuthenticatedAppShape.deliveries}.
1384
+ *
1385
+ * @public
1386
+ */
1387
+ interface DeliveriesOptions {
1388
+ /**
1389
+ * Only deliveries that succeeded or failed, filtered by GitHub. A delivery
1390
+ * is a failure when your endpoint did not answer with a 2xx.
1391
+ */
1392
+ readonly status?: "success" | "failure" | undefined;
1393
+ /** How far to page. Unset, pages of 100 until GitHub stops. */
1394
+ readonly page?: PageOptions | undefined;
1395
+ }
1396
+ /**
1397
+ * The app-level REST surface: the app's own record, its webhook deliveries and
1398
+ * removing an installation.
1399
+ *
1400
+ * @remarks
1401
+ * Every member needs a `GitHubClient` authenticated **as the app** (an App
1402
+ * JWT), which is what {@link GitHubApp.appClientLayer} provides; an
1403
+ * installation token answers these routes with 401. No member needs a `Repo`.
1404
+ *
1405
+ * @public
1406
+ */
1407
+ interface AuthenticatedAppShape {
1408
+ /** The app itself (`GET /app`). */
1409
+ readonly get: () => Effect.Effect<AppInfo, GitHubError>;
1410
+ /**
1411
+ * The app's webhook deliveries, newest first (`GET /app/hook/deliveries`).
1412
+ *
1413
+ * @remarks
1414
+ * **Lazy in requests**: a page is fetched only when the stream is pulled
1415
+ * past the previous one, so `Stream.takeWhile` on `deliveredAt` stops a
1416
+ * sweep at the window's edge without reading the rest of the log. GitHub
1417
+ * pages this route by cursor; the walk follows its `Link` header.
1418
+ *
1419
+ * Each delivery is decoded as it arrives; a malformed one fails the stream
1420
+ * with a `decode` `GitHubError`.
1421
+ */
1422
+ readonly deliveries: (options?: DeliveriesOptions) => Stream.Stream<DeliveryAttempt, GitHubError>;
1423
+ /**
1424
+ * One delivery attempt (`GET /app/hook/deliveries/{delivery_id}`).
1425
+ *
1426
+ * @remarks
1427
+ * Projected onto the same {@link DeliveryAttempt} the listing answers; the
1428
+ * request and response payloads GitHub also returns are not kept. Read them
1429
+ * through the typed request surface when you need them.
1430
+ */
1431
+ readonly delivery: (deliveryId: number) => Effect.Effect<DeliveryAttempt, GitHubError>;
1432
+ /**
1433
+ * Ask GitHub to deliver an attempt's event again
1434
+ * (`POST /app/hook/deliveries/{delivery_id}/attempts`).
1435
+ *
1436
+ * @remarks
1437
+ * GitHub answers 202: the redelivery is queued, not done, and appears in
1438
+ * {@link AuthenticatedAppShape.deliveries} as a new attempt with the same
1439
+ * `guid` and `redelivery: true`.
1440
+ */
1441
+ readonly redeliver: (deliveryId: number) => Effect.Effect<void, GitHubError>;
1442
+ /**
1443
+ * Uninstall the app from an account
1444
+ * (`DELETE /app/installations/{installation_id}`).
1445
+ *
1446
+ * @remarks
1447
+ * Irreversible from the app's side: only the account can install it again.
1448
+ * An installation that does not exist (or is already gone) fails with
1449
+ * `GitHubError { kind: "notFound" }`.
1450
+ */
1451
+ readonly uninstall: (installationId: number) => Effect.Effect<void, GitHubError>;
1452
+ }
1453
+ declare const AuthenticatedApp_base: Context.ServiceClass<AuthenticatedApp, "@effected/github/AuthenticatedApp", AuthenticatedAppShape>;
1454
+ /**
1455
+ * The app-level REST surface: the app's own record, its webhook delivery log
1456
+ * and redelivery, and uninstalling.
1457
+ *
1458
+ * @remarks
1459
+ * Provide {@link AuthenticatedApp.layer} over an App-JWT client from
1460
+ * {@link GitHubApp.appClientLayer}. This module imports no JWT signer: the
1461
+ * credential is the client's business, so a test drives it with any client.
1462
+ *
1463
+ * @example
1464
+ * ```ts
1465
+ * import { AuthenticatedApp, GitHubApp } from "@effected/github";
1466
+ * import { DateTime, Effect, Layer, Redacted, Stream } from "effect";
1467
+ *
1468
+ * // Redeliver every failed delivery from the last hour.
1469
+ * const sweep = Effect.gen(function* () {
1470
+ * const app = yield* AuthenticatedApp;
1471
+ * const since = DateTime.subtract(yield* DateTime.now, { hours: 1 });
1472
+ * yield* app.deliveries({ status: "failure" }).pipe(
1473
+ * Stream.takeWhile((delivery) => DateTime.isGreaterThan(DateTime.makeUnsafe(delivery.deliveredAt), since)),
1474
+ * Stream.runForEach((delivery) => app.redeliver(delivery.id)),
1475
+ * );
1476
+ * });
1477
+ *
1478
+ * const layer = AuthenticatedApp.layer.pipe(
1479
+ * Layer.provide(
1480
+ * GitHubApp.appClientLayer({
1481
+ * appId: "12345",
1482
+ * privateKey: Redacted.make("-----BEGIN RSA PRIVATE KEY-----\n..."),
1483
+ * }),
1484
+ * ),
1485
+ * );
1486
+ *
1487
+ * Effect.runPromise(Effect.provide(sweep, layer));
1488
+ * ```
1489
+ *
1490
+ * @public
1491
+ */
1492
+ export declare class AuthenticatedApp extends AuthenticatedApp_base {
1493
+ /** The live service, built over an App-JWT `GitHubClient`. */
1494
+ static readonly layer: Layer.Layer<AuthenticatedApp, never, GitHubClient>;
1495
+ /** An in-memory double; unstubbed members die naming themselves. */
1496
+ static readonly makeTest: (overrides?: Partial<AuthenticatedAppShape>) => AuthenticatedAppShape;
1497
+ /** {@link AuthenticatedApp.makeTest} behind a `Layer`. */
1498
+ static readonly layerTest: (overrides?: Partial<AuthenticatedAppShape>) => Layer.Layer<AuthenticatedApp>;
1499
+ }
1500
+ //#endregion
1306
1501
  //#region src/CheckRun.d.ts
1307
1502
  /** How a check run finished. @public */
1308
1503
  export declare const CheckConclusion: Schema.Literals<readonly ["success", "failure", "neutral", "cancelled", "timed_out", "action_required", "skipped"]>;
1504
+ /**
1505
+ * The phase of its lifecycle a check run is in, as GitHub reports it.
1506
+ *
1507
+ * @remarks
1508
+ * `"waiting"`, `"requested"` and `"pending"` are reserved for GitHub Actions
1509
+ * runs; an integrator can only write `"queued"`, `"in_progress"` and, through
1510
+ * {@link CheckRunShape.complete}, `"completed"`.
1511
+ *
1512
+ * @public
1513
+ */
1514
+ export declare const CheckRunStatus: Schema.Literals<readonly ["queued", "in_progress", "completed", "waiting", "requested", "pending"]>;
1515
+ /**
1516
+ * How a check run finished, as GitHub reports it: every
1517
+ * {@link CheckConclusion} plus `"stale"`.
1518
+ *
1519
+ * @remarks
1520
+ * GitHub's check-run response schema omits `"stale"`, but its update
1521
+ * endpoint documents it: *"You cannot change a check run conclusion to
1522
+ * `stale`, only GitHub can set this."* GitHub sets it on a run left
1523
+ * incomplete too long, so a read that refused it would fail on any commit
1524
+ * carrying one. It is read-only, which is why {@link CheckConclusion}, the
1525
+ * write set, does not include it.
1526
+ *
1527
+ * @public
1528
+ */
1529
+ export declare const ReportedCheckConclusion: Schema.Literals<readonly ["success", "failure", "neutral", "cancelled", "timed_out", "action_required", "skipped", "stale"]>;
1309
1530
  /** How serious an annotation is. @public */
1310
1531
  export declare const AnnotationLevel: Schema.Literals<readonly ["notice", "warning", "failure"]>;
1311
1532
  declare const Annotation_base: Schema.Class<Annotation, Schema.Struct<{
@@ -1363,22 +1584,77 @@ export declare class CheckRunOutput extends CheckRunOutput_base {
1363
1584
  */
1364
1585
  truncated(): CheckRunOutput;
1365
1586
  }
1587
+ declare const ReportedCheckRunOutput_base: Schema.Class<ReportedCheckRunOutput, Schema.Struct<{
1588
+ /** The output's title; `null` when the run has none. */
1589
+ readonly title: Schema.NullOr<Schema.String>;
1590
+ /** The output's markdown summary; `null` when the run has none. */
1591
+ readonly summary: Schema.NullOr<Schema.String>;
1592
+ /** How many annotations the run carries (wire `annotations_count`). */
1593
+ readonly annotationsCount: Schema.Int;
1594
+ }>, {}>;
1595
+ /**
1596
+ * The rendered output a check run reports: its title and summary, and how
1597
+ * many annotations it carries.
1598
+ *
1599
+ * @remarks
1600
+ * The read-side counterpart of {@link CheckRunOutput}. It leaves out the
1601
+ * long-form `text` deliberately: it can run to 65535 bytes, and a caller
1602
+ * listing a commit's runs rarely wants it. Read the run's full output through
1603
+ * the typed request surface when you do.
1604
+ *
1605
+ * @public
1606
+ */
1607
+ export declare class ReportedCheckRunOutput extends ReportedCheckRunOutput_base {}
1366
1608
  declare const CheckRunRef_base: Schema.Class<CheckRunRef, Schema.Struct<{
1367
1609
  readonly id: Schema.Int;
1368
1610
  readonly name: Schema.String;
1369
- /** The web URL. */
1611
+ /** The web URL (wire `html_url`), or `""` when GitHub reported none. See also `htmlUrl`. */
1370
1612
  readonly url: Schema.String;
1371
- readonly status: Schema.String;
1613
+ /** The run's lifecycle phase. */
1614
+ readonly status: Schema.Literals<readonly ["queued", "in_progress", "completed", "waiting", "requested", "pending"]>;
1372
1615
  /**
1373
1616
  * The integrator's own id for the run (wire `external_id`), when it has
1374
1617
  * one. GitHub reports a run created without one as `null` or `""`; both
1375
1618
  * leave this absent.
1376
1619
  */
1377
1620
  readonly externalId: Schema.optionalKey<Schema.String>;
1621
+ /** The commit the run checks (wire `head_sha`). */
1622
+ readonly headSha: Schema.optionalKey<Schema.String>;
1623
+ /** The run's GraphQL node id (wire `node_id`). */
1624
+ readonly nodeId: Schema.optionalKey<Schema.String>;
1625
+ /** How the run finished; `null` until it completes. */
1626
+ readonly conclusion: Schema.optionalKey<Schema.NullOr<Schema.Literals<readonly ["success", "failure", "neutral", "cancelled", "timed_out", "action_required", "skipped", "stale"]>>>;
1627
+ /** When the run started, as GitHub's ISO 8601 string; `null` for a run that has not. */
1628
+ readonly startedAt: Schema.optionalKey<Schema.NullOr<Schema.String>>;
1629
+ /** When the run completed, as GitHub's ISO 8601 string; `null` for a run that has not. */
1630
+ readonly completedAt: Schema.optionalKey<Schema.NullOr<Schema.String>>;
1631
+ /** The integrator's link for the run (wire `details_url`). */
1632
+ readonly detailsUrl: Schema.optionalKey<Schema.NullOr<Schema.String>>;
1633
+ /** The web URL (wire `html_url`), `null` preserved. */
1634
+ readonly htmlUrl: Schema.optionalKey<Schema.NullOr<Schema.String>>;
1635
+ /** The run's REST API URL (wire `url`). */
1636
+ readonly apiUrl: Schema.optionalKey<Schema.String>;
1637
+ /** The check suite the run belongs to (wire `check_suite.id`); `null` when GitHub reported none. */
1638
+ readonly checkSuiteId: Schema.optionalKey<Schema.NullOr<Schema.Int>>;
1639
+ /** The run's title, summary and annotation count. */
1640
+ readonly output: Schema.optionalKey<typeof ReportedCheckRunOutput>;
1378
1641
  }>, {}>;
1379
1642
  /**
1380
1643
  * A check run as GitHub reports it.
1381
1644
  *
1645
+ * @remarks
1646
+ * Every field beyond the original five (the four required ones and
1647
+ * `externalId`) is optional, so a test double built with
1648
+ * `CheckRunRef.make({ id, name, url, status })` stays valid; a run decoded
1649
+ * from a GitHub response carries all of them, because GitHub always sends
1650
+ * them. A nullable field is `null` when GitHub reported `null`.
1651
+ *
1652
+ * **Three URLs, named apart.** `url` is the **web** URL (wire `html_url`, or
1653
+ * `""` when GitHub reported none), kept under that name so existing callers
1654
+ * read what they always read. `htmlUrl` is the same wire field with its
1655
+ * `null` preserved, `apiUrl` is the REST URL (wire `url`), and `detailsUrl`
1656
+ * is the integrator's own link (wire `details_url`).
1657
+ *
1382
1658
  * @public
1383
1659
  */
1384
1660
  export declare class CheckRunRef extends CheckRunRef_base {}
@@ -1419,6 +1695,29 @@ interface UpdateCheckRunOptions {
1419
1695
  /** Where the integrator's full details live (wire `details_url`). */
1420
1696
  readonly detailsUrl?: string | undefined;
1421
1697
  }
1698
+ /**
1699
+ * Options for {@link CheckRunShape.list}.
1700
+ *
1701
+ * @public
1702
+ */
1703
+ interface ListCheckRunsOptions {
1704
+ /** Only runs with this name (wire `check_name`). */
1705
+ readonly checkName?: string | undefined;
1706
+ /** Only runs created by this GitHub App (wire `app_id`). */
1707
+ readonly appId?: number | undefined;
1708
+ /**
1709
+ * Only runs in this phase. GitHub filters on these three only; the
1710
+ * Actions-reserved phases are not a filter it accepts.
1711
+ */
1712
+ readonly status?: "queued" | "in_progress" | "completed" | undefined;
1713
+ /**
1714
+ * `"latest"` (GitHub's default) answers only the newest run per name;
1715
+ * `"all"` answers every run, re-runs included.
1716
+ */
1717
+ readonly filter?: "latest" | "all" | undefined;
1718
+ /** How far to page. Unset, every page is read, 100 runs at a time. */
1719
+ readonly page?: PageOptions | undefined;
1720
+ }
1422
1721
  /**
1423
1722
  * Options for {@link CheckRunShape.complete}.
1424
1723
  *
@@ -1480,6 +1779,28 @@ interface CheckRunShape {
1480
1779
  * handling sees a missing run or a revoked token the same way either way.
1481
1780
  */
1482
1781
  readonly update: (id: number, output?: CheckRunOutput, options?: UpdateCheckRunOptions) => Effect.Effect<void, GitHubError, Repo>;
1782
+ /**
1783
+ * {@link CheckRunShape.update}, answering the run as GitHub reports it
1784
+ * after the PATCH.
1785
+ *
1786
+ * @remarks
1787
+ * The same single request, with the same omission rules; the difference is
1788
+ * only that GitHub's response is decoded into a {@link CheckRunRef} rather
1789
+ * than discarded. A separate member rather than a new return type on
1790
+ * `update`, so a test double that stubs `update` with `Effect.void` keeps
1791
+ * compiling.
1792
+ */
1793
+ readonly updateRef: (id: number, output?: CheckRunOutput, options?: UpdateCheckRunOptions) => Effect.Effect<CheckRunRef, GitHubError, Repo>;
1794
+ /**
1795
+ * The check runs on a commit, newest per name unless `options.filter` is
1796
+ * `"all"`.
1797
+ *
1798
+ * @remarks
1799
+ * `ref` is a commit SHA, a branch name or a tag name. Every page is read
1800
+ * unless `options.page` bounds the walk, so a filter that matches past
1801
+ * page one is still answered in full.
1802
+ */
1803
+ readonly list: (ref: string, options?: ListCheckRunsOptions) => Effect.Effect<ReadonlyArray<CheckRunRef>, GitHubError, Repo>;
1483
1804
  /**
1484
1805
  * The newest run on `headSha` named `name` whose external id is
1485
1806
  * `externalId`; none when there is no such run.
@@ -1504,6 +1825,17 @@ interface CheckRunShape {
1504
1825
  * workflow run that produced it.
1505
1826
  */
1506
1827
  readonly complete: (id: number, conclusion: (typeof CheckConclusion.literals)[number], output?: CheckRunOutput, options?: CompleteCheckRunOptions) => Effect.Effect<void, GitHubError, Repo>;
1828
+ /**
1829
+ * {@link CheckRunShape.complete}, answering the finished run as GitHub
1830
+ * reports it after the PATCH.
1831
+ *
1832
+ * @remarks
1833
+ * The same single request, with the same `completed_at` stamp and output
1834
+ * byte cap; GitHub's response is decoded into a {@link CheckRunRef} rather
1835
+ * than discarded. A separate member for the same reason as
1836
+ * {@link CheckRunShape.updateRef}.
1837
+ */
1838
+ readonly completeRef: (id: number, conclusion: (typeof CheckConclusion.literals)[number], output?: CheckRunOutput, options?: CompleteCheckRunOptions) => Effect.Effect<CheckRunRef, GitHubError, Repo>;
1507
1839
  /**
1508
1840
  * Run `use` inside a check run, concluding it however `use` exits.
1509
1841
  *
@@ -2243,6 +2575,37 @@ export declare class AppIdentity extends AppIdentity_base {
2243
2575
  /** The committer identity for this app. */
2244
2576
  botIdentity(): BotIdentity;
2245
2577
  }
2578
+ declare const BotUser_base: Schema.Class<BotUser, Schema.Struct<{
2579
+ /** The bot user's numeric id. */
2580
+ readonly id: Schema.Int;
2581
+ /** The bot user's login, `<slug>[bot]`. */
2582
+ readonly login: Schema.String;
2583
+ }>, {}>;
2584
+ /**
2585
+ * An app's bot user: the account its installation tokens act as.
2586
+ *
2587
+ * @remarks
2588
+ * `id` is what to compare against an actor id on an event, such as
2589
+ * `workflow_run.triggering_actor.id`: a login can be renamed, an id cannot.
2590
+ *
2591
+ * @public
2592
+ */
2593
+ export declare class BotUser extends BotUser_base {}
2594
+ /**
2595
+ * What {@link GitHubAppShape.botUser} looks up.
2596
+ *
2597
+ * @public
2598
+ */
2599
+ interface BotUserRequest {
2600
+ /** The app's slug; the bot user is `<slug>[bot]`. */
2601
+ readonly slug: string;
2602
+ /**
2603
+ * An installation token to authenticate the lookup with. Without one the
2604
+ * lookup runs unauthenticated, at GitHub's 60-requests-per-hour-per-IP
2605
+ * limit: `GET /users/{username}` rejects an App JWT.
2606
+ */
2607
+ readonly installationToken?: Redacted.Redacted<string> | undefined;
2608
+ }
2246
2609
  declare const Installation_base: Schema.Class<Installation, Schema.Struct<{
2247
2610
  /** The installation id, which is what a token is minted against. */
2248
2611
  readonly id: Schema.Int;
@@ -2536,6 +2899,17 @@ interface GitHubAppShape {
2536
2899
  readonly identity: (request: AppCredentials & {
2537
2900
  readonly installationToken?: Redacted.Redacted<string> | undefined;
2538
2901
  }) => Effect.Effect<AppIdentity, GitHubAppError>;
2902
+ /**
2903
+ * The app's bot user, `GET /users/{slug}[bot]`.
2904
+ *
2905
+ * @remarks
2906
+ * Unlike {@link GitHubAppShape.identity}, which treats the bot user as
2907
+ * optional enrichment and omits it when the lookup fails, this fails with
2908
+ * `kind: "identity"` — for a caller that authorizes on the bot's id, a
2909
+ * missing id is an error, not a degraded answer. Get the slug from
2910
+ * `identity` or from `AuthenticatedApp.get`.
2911
+ */
2912
+ readonly botUser: (request: BotUserRequest) => Effect.Effect<BotUser, GitHubAppError>;
2539
2913
  /** Every installation of the app. */
2540
2914
  readonly installations: (credentials: AppCredentials) => Effect.Effect<ReadonlyArray<Installation>, GitHubAppError>;
2541
2915
  }
@@ -4253,6 +4627,25 @@ export declare class WorkflowRunStatus extends WorkflowRunStatus_base {
4253
4627
  /** Has the run finished, whatever the outcome? */
4254
4628
  get isDone(): boolean;
4255
4629
  }
4630
+ declare const DispatchedRun_base: Schema.Class<DispatchedRun, Schema.Struct<{
4631
+ /** The created run's numeric id. */
4632
+ readonly runId: Schema.Int;
4633
+ /** The run's API URL. */
4634
+ readonly runUrl: Schema.String;
4635
+ /** The run's web URL. */
4636
+ readonly htmlUrl: Schema.String;
4637
+ }>, {}>;
4638
+ /**
4639
+ * The run a `workflow_dispatch` created, as GitHub reports it when asked.
4640
+ *
4641
+ * @remarks
4642
+ * Returned by {@link WorkflowDispatchShape.dispatchWithRun}. `runId` is usable
4643
+ * directly with {@link WorkflowDispatchShape.runStatus} and
4644
+ * {@link WorkflowDispatchShape.cancelRun}.
4645
+ *
4646
+ * @public
4647
+ */
4648
+ export declare class DispatchedRun extends DispatchedRun_base {}
4256
4649
  /**
4257
4650
  * One workflow defined in the repository.
4258
4651
  *
@@ -4293,8 +4686,34 @@ interface PollOptions {
4293
4686
  * @public
4294
4687
  */
4295
4688
  interface WorkflowDispatchShape {
4296
- /** Fire a `workflow_dispatch` event. GitHub answers 204 with no run id. */
4689
+ /**
4690
+ * Fire a `workflow_dispatch` event and discard GitHub's answer; use
4691
+ * {@link WorkflowDispatchShape.dispatchWithRun} when the run id is needed.
4692
+ */
4297
4693
  readonly dispatch: (workflow: string, ref: string, inputs?: Record<string, string>) => Effect.Effect<void, GitHubError, Repo>;
4694
+ /**
4695
+ * Fire a `workflow_dispatch` event and report the run it created.
4696
+ *
4697
+ * @remarks
4698
+ * Sends the same request as {@link WorkflowDispatchShape.dispatch} with
4699
+ * `return_run_details: true`. GitHub then answers 200 with the run's id and
4700
+ * URLs, which arrive as `Option.some` of a {@link DispatchedRun}; a 200 body
4701
+ * that does not have that shape fails with a `decode` `GitHubError`.
4702
+ *
4703
+ * A 204 with no body is `Option.none()`. That is what a GitHub Enterprise
4704
+ * Server predating the field answers — it ignores `return_run_details` and
4705
+ * still dispatches — so it is **not a failure**: the workflow was dispatched,
4706
+ * the server just did not say which run it created.
4707
+ *
4708
+ * Under `GitHubClient.layerFixture`, stub the 204 the way every other
4709
+ * no-body route is stubbed: answer the dispatch route with `null`. `""`
4710
+ * (what octokit itself hands back for an empty body) works too.
4711
+ *
4712
+ * Every failure of the request itself (a 404 for an unknown workflow, a 422
4713
+ * for a workflow without a `workflow_dispatch` trigger, …) is the
4714
+ * `GitHubError` the client classified, passed through unchanged.
4715
+ */
4716
+ readonly dispatchWithRun: (workflow: string, ref: string, inputs?: Record<string, string>) => Effect.Effect<Option.Option<DispatchedRun>, GitHubError, Repo>;
4298
4717
  /** Read one workflow run's status. */
4299
4718
  readonly runStatus: (runId: number) => Effect.Effect<WorkflowRunStatus, GitHubError, Repo>;
4300
4719
  /**
@@ -4330,8 +4749,15 @@ interface WorkflowDispatchShape {
4330
4749
  * The wait is `Effect.repeat` with a predicate over the **success** value, so
4331
4750
  * "not finished yet" is never an error. If the run is not found finished
4332
4751
  * within `poll.timeout`, it fails with a `rejected` `GitHubError` (status
4333
- * 408). The run is matched by branch, creation time and workflow path, so
4334
- * concurrent dispatches of the same workflow on the same ref can be confused.
4752
+ * 408).
4753
+ *
4754
+ * The run is identified by {@link WorkflowDispatchShape.dispatchWithRun}:
4755
+ * when GitHub reports the run it created, exactly that run is polled, so
4756
+ * concurrent dispatches cannot be confused. When it does not (a 204 from a
4757
+ * GitHub Enterprise Server predating `return_run_details`), the run is found
4758
+ * instead by branch, creation time and workflow path — and on that fallback
4759
+ * alone, concurrent dispatches of the same workflow on the same ref can be
4760
+ * confused.
4335
4761
  */
4336
4762
  readonly dispatchAndWait: (workflow: string, ref: string, options?: {
4337
4763
  readonly inputs?: Record<string, string> | undefined;
@@ -4374,5 +4800,5 @@ export declare class WorkflowDispatch extends WorkflowDispatch_base {
4374
4800
  static readonly layerTest: (overrides?: Partial<WorkflowDispatchShape>) => Layer.Layer<WorkflowDispatch>;
4375
4801
  }
4376
4802
  //#endregion
4377
- export { type ActionsOidcVerifyOptions, type AppCredentials, type AppliedSettings, type ArtifactMetadataShape, type AttestationShape, type BareLineReference, type BranchOutcome, CLOSING_KEYWORDS, type CachedToken, type CachedTokenRequest, type CheckRunShape, type ClosingKeyword, type CodeScanningSetup, type CodeScanningShape, type CompleteCheckRunOptions, type ConcludeCheckRun, type CreateCheckRunOptions, type DeploymentEnvironmentInfo, type DeploymentEnvironmentShape, type GitBranchShape, type GitCommitShape, type GitHubAppOptions, type GitHubAppShape, type GitHubClientOptions, type GitHubClientShape, type GitHubCommitShape, type GitHubContentShape, type GitHubIssueShape, type GitHubReleaseShape, type GitHubRepositoryShape, type GitTagShape, type InstallationTokenStoreShape, type IssueReference, type LatestSemverOptions, type OwnerType, type PollOptions, type PullRequestCommentShape, type PullRequestShape, type RecordedCall, type RepositoryPatch, type RepositoryPatchDraft, type RepositorySecretShape, type RepositorySecurityShape, type RepositorySettings, type RepositoryVariableShape, type Data as RestData, type RequestExtras as RestExtras, type Item as RestItem, type PaginatingRoute as RestPaginatingRoute, type Params as RestParams, type Response as RestResponse, type Route as RestRoute, type RetryableFailure, type RulesetInfo, type RulesetPayload, type RulesetShape, type SecretInfo, type SecretScope, type TokenRequest, type UpdateCheckRunOptions, type UpsertedPullRequest, type VariableInfo, type VersionFromTag, type WorkflowDispatchShape, type WorkflowInfo, harvestIssueReferences, parseBareLineReference };
4803
+ export { type ActionsOidcVerifyOptions, type AppCredentials, type AppliedSettings, type ArtifactMetadataShape, type AttestationShape, type AuthenticatedAppShape, type BareLineReference, type BotUserRequest, type BranchOutcome, CLOSING_KEYWORDS, type CachedToken, type CachedTokenRequest, type CheckRunShape, type ClosingKeyword, type CodeScanningSetup, type CodeScanningShape, type CompleteCheckRunOptions, type ConcludeCheckRun, type CreateCheckRunOptions, type DeliveriesOptions, type DeploymentEnvironmentInfo, type DeploymentEnvironmentShape, type GitBranchShape, type GitCommitShape, type GitHubAppOptions, type GitHubAppShape, type GitHubClientOptions, type GitHubClientShape, type GitHubCommitShape, type GitHubContentShape, type GitHubIssueShape, type GitHubReleaseShape, type GitHubRepositoryShape, type GitTagShape, type InstallationTokenStoreShape, type IssueReference, type LatestSemverOptions, type ListCheckRunsOptions, type OwnerType, type PollOptions, type PullRequestCommentShape, type PullRequestShape, type RecordedCall, type RepositoryPatch, type RepositoryPatchDraft, type RepositorySecretShape, type RepositorySecurityShape, type RepositorySettings, type RepositoryVariableShape, type Data as RestData, type RequestExtras as RestExtras, type Item as RestItem, type PaginatingRoute as RestPaginatingRoute, type Params as RestParams, type Response as RestResponse, type Route as RestRoute, type RetryableFailure, type RulesetInfo, type RulesetPayload, type RulesetShape, type SecretInfo, type SecretScope, type TokenRequest, type UpdateCheckRunOptions, type UpsertedPullRequest, type VariableInfo, type VersionFromTag, type WorkflowDispatchShape, type WorkflowInfo, harvestIssueReferences, parseBareLineReference };
4378
4804
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -6,13 +6,14 @@ import { GitHubClient, GitHubFixtures, RawFailure } from "./GitHubClient.js";
6
6
  import { InvalidRepoRefError, Repo, RepoRef } from "./Repo.js";
7
7
  import { ArtifactMetadata, StorageRecordInput } from "./ArtifactMetadata.js";
8
8
  import { Attestation, AttestationListEntry, AttestationRecord } from "./Attestation.js";
9
- import { Annotation, AnnotationLevel, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef } from "./CheckRun.js";
9
+ import { AppInfo, AuthenticatedApp, DeliveryAttempt } from "./AuthenticatedApp.js";
10
+ import { Annotation, AnnotationLevel, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef, CheckRunStatus, ReportedCheckConclusion, ReportedCheckRunOutput } from "./CheckRun.js";
10
11
  import { CodeScanning } from "./CodeScanning.js";
11
12
  import { DeploymentEnvironment } from "./DeploymentEnvironment.js";
12
13
  import { GitBranch } from "./GitBranch.js";
13
14
  import { CommitRef, FileChange, FileContent, FileDeletion, FileMode, GitCommit } from "./GitCommit.js";
14
15
  import { InstallationTokenStore } from "./InstallationTokenStore.js";
15
- import { AppIdentity, BotIdentity, GitHubApp, GitHubAppError, Installation, InstallationToken } from "./GitHubApp.js";
16
+ import { AppIdentity, BotIdentity, BotUser, GitHubApp, GitHubAppError, Installation, InstallationToken } from "./GitHubApp.js";
16
17
  import { CommitComparison, CommitFile, CommitSummary, FileStatus, GitHubCommit } from "./GitHubCommit.js";
17
18
  import { GitHubContent } from "./GitHubContent.js";
18
19
  import { CommentMarker, CommentRecord, PullRequestComment } from "./PullRequestComment.js";
@@ -27,7 +28,7 @@ import { RepositorySecurity } from "./RepositorySecurity.js";
27
28
  import { RepositoryVariable } from "./RepositoryVariable.js";
28
29
  import { Ruleset } from "./Ruleset.js";
29
30
  import { ExtraPermission, PermissionGap, PermissionLevel, PermissionResult, TokenPermissionError, TokenPermissions } from "./TokenPermissions.js";
30
- import { WorkflowDispatch, WorkflowRunStatus } from "./WorkflowDispatch.js";
31
+ import { DispatchedRun, WorkflowDispatch, WorkflowRunStatus } from "./WorkflowDispatch.js";
31
32
  import { CLOSING_KEYWORDS, harvestIssueReferences, parseBareLineReference } from "@effected/github-references";
32
33
 
33
- export { ActionsOidc, ActionsOidcClaims, Annotation, AnnotationLevel, AppIdentity, ArtifactMetadata, Attestation, AttestationListEntry, AttestationRecord, BotIdentity, CLOSING_KEYWORDS, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef, CodeScanning, CommentMarker, CommentOnceResult, CommentRecord, CommitComparison, CommitFile, CommitRef, CommitSummary, DeploymentEnvironment, ExtraPermission, FileChange, FileContent, FileDeletion, FileMode, FileStatus, GRAPHQL_ONLY_SETTINGS, GitBranch, GitCommit, GitHubApp, GitHubAppError, GitHubClient, GitHubCommit, GitHubContent, GitHubError, GitHubErrorKind, GitHubFixtures, GitHubGraphQLError, GitHubIssue, GitHubRelease, GitHubRepository, GitHubValidationCode, GitHubValidationEntry, GitTag, GraphQLDocument, GraphQLErrorEntry, Installation, InstallationToken, InstallationTokenStore, InvalidRepoRefError, IssueInfo, LinkedIssue, MergeMethod, PageOptions, PermissionGap, PermissionLevel, PermissionResult, PullRequest, PullRequestComment, PullRequestInfo, RateLimitSnapshot, RawFailure, ReleaseAsset, ReleaseInfo, Repo, RepoRef, RepositorySecret, RepositorySecurity, RepositoryVariable, RetryPolicy, Ruleset, SECURITY_ANALYSIS_STATUS_FIELDS, SemverTag, StorageRecordInput, TagRef, TokenPermissionError, TokenPermissions, WorkflowDispatch, WorkflowRunStatus, harvestIssueReferences, parseBareLineReference, repositoryPatch, transformSecurityAndAnalysis, versionFromTag };
34
+ export { ActionsOidc, ActionsOidcClaims, Annotation, AnnotationLevel, AppIdentity, AppInfo, ArtifactMetadata, Attestation, AttestationListEntry, AttestationRecord, AuthenticatedApp, BotIdentity, BotUser, CLOSING_KEYWORDS, CheckConclusion, CheckRun, CheckRunOutput, CheckRunRef, CheckRunStatus, CodeScanning, CommentMarker, CommentOnceResult, CommentRecord, CommitComparison, CommitFile, CommitRef, CommitSummary, DeliveryAttempt, DeploymentEnvironment, DispatchedRun, ExtraPermission, FileChange, FileContent, FileDeletion, FileMode, FileStatus, GRAPHQL_ONLY_SETTINGS, GitBranch, GitCommit, GitHubApp, GitHubAppError, GitHubClient, GitHubCommit, GitHubContent, GitHubError, GitHubErrorKind, GitHubFixtures, GitHubGraphQLError, GitHubIssue, GitHubRelease, GitHubRepository, GitHubValidationCode, GitHubValidationEntry, GitTag, GraphQLDocument, GraphQLErrorEntry, Installation, InstallationToken, InstallationTokenStore, InvalidRepoRefError, IssueInfo, LinkedIssue, MergeMethod, PageOptions, PermissionGap, PermissionLevel, PermissionResult, PullRequest, PullRequestComment, PullRequestInfo, RateLimitSnapshot, RawFailure, ReleaseAsset, ReleaseInfo, Repo, RepoRef, ReportedCheckConclusion, ReportedCheckRunOutput, RepositorySecret, RepositorySecurity, RepositoryVariable, RetryPolicy, Ruleset, SECURITY_ANALYSIS_STATUS_FIELDS, SemverTag, StorageRecordInput, TagRef, TokenPermissionError, TokenPermissions, WorkflowDispatch, WorkflowRunStatus, harvestIssueReferences, parseBareLineReference, repositoryPatch, transformSecurityAndAnalysis, versionFromTag };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/github",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "private": false,
5
5
  "description": "Typed GitHub REST and GraphQL services over the octokit core request surface, with app auth and resource helpers.",
6
6
  "keywords": [
@@ -38,9 +38,9 @@
38
38
  "./package.json": "./package.json"
39
39
  },
40
40
  "dependencies": {
41
- "@effected/github-references": "^0.7.0",
42
- "@effected/jwt": "^0.1.0",
43
- "@effected/semver": "^0.11.0",
41
+ "@effected/github-references": "^0.7.1",
42
+ "@effected/jwt": "^0.1.1",
43
+ "@effected/semver": "^0.11.1",
44
44
  "@octokit/core": "^7.0.6",
45
45
  "@octokit/plugin-paginate-rest": "^16.0.0",
46
46
  "@octokit/types": "^18.0.0",
@@ -48,7 +48,7 @@
48
48
  "tweetnacl": "1.0.3"
49
49
  },
50
50
  "peerDependencies": {
51
- "effect": "^4.0.0"
51
+ "effect": "4.0.2"
52
52
  },
53
53
  "engines": {
54
54
  "node": ">=24.11.0"