@usine/github 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -4
- package/dist/access.d.ts +48 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +53 -0
- package/dist/access.js.map +1 -0
- package/dist/credentials.d.ts +28 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +22 -0
- package/dist/credentials.js.map +1 -0
- package/dist/error.d.ts +36 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +48 -0
- package/dist/error.js.map +1 -0
- package/dist/github-app.d.ts +17 -10
- package/dist/github-app.d.ts.map +1 -1
- package/dist/github-app.js +31 -16
- package/dist/github-app.js.map +1 -1
- package/dist/http.d.ts +3 -4
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +4 -4
- package/dist/http.js.map +1 -1
- package/dist/installation.d.ts +48 -0
- package/dist/installation.d.ts.map +1 -0
- package/dist/installation.js +40 -0
- package/dist/installation.js.map +1 -0
- package/dist/item-writer.d.ts +7 -6
- package/dist/item-writer.d.ts.map +1 -1
- package/dist/item-writer.js +5 -4
- package/dist/item-writer.js.map +1 -1
- package/dist/jwt.d.ts +6 -5
- package/dist/jwt.d.ts.map +1 -1
- package/dist/jwt.js +4 -4
- package/dist/jwt.js.map +1 -1
- package/dist/label-writer.d.ts +23 -0
- package/dist/label-writer.d.ts.map +1 -0
- package/dist/label-writer.js +54 -0
- package/dist/label-writer.js.map +1 -0
- package/dist/local-secrets.d.ts +5 -5
- package/dist/local-secrets.d.ts.map +1 -1
- package/dist/local-secrets.js +5 -5
- package/dist/local-secrets.js.map +1 -1
- package/dist/polling/content.d.ts +3 -0
- package/dist/polling/content.d.ts.map +1 -0
- package/dist/polling/content.js +24 -0
- package/dist/polling/content.js.map +1 -0
- package/dist/polling/detection.d.ts +55 -0
- package/dist/polling/detection.d.ts.map +1 -0
- package/dist/polling/detection.js +49 -0
- package/dist/polling/detection.js.map +1 -0
- package/dist/polling/labels.d.ts +31 -0
- package/dist/polling/labels.d.ts.map +1 -0
- package/dist/polling/labels.js +29 -0
- package/dist/polling/labels.js.map +1 -0
- package/dist/polling/{model.d.ts → payload.d.ts} +7 -66
- package/dist/polling/payload.d.ts.map +1 -0
- package/dist/polling/{model.js → payload.js} +12 -72
- package/dist/polling/payload.js.map +1 -0
- package/dist/polling/polling.d.ts +15 -9
- package/dist/polling/polling.d.ts.map +1 -1
- package/dist/polling/polling.js +49 -44
- package/dist/polling/polling.js.map +1 -1
- package/package.json +17 -5
- package/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -7
- package/dist/index.js.map +0 -1
- package/dist/model.d.ts +0 -128
- package/dist/model.d.ts.map +0 -1
- package/dist/model.js +0 -133
- package/dist/model.js.map +0 -1
- package/dist/polling/model.d.ts.map +0 -1
- package/dist/polling/model.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detection.js","sourceRoot":"","sources":["../../src/polling/detection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhD,4FAA4F;AAC5F,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAGrF,sGAAsG;AACtG,MAAM,OAAO,UAAW,SAAQ,MAAM,CAAC,KAAK,CAAa,0BAA0B,CAAC,CAAC;IACnF,SAAS,EAAE,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,qBAAqB,CAAC;CACjE,CAAC;IACA,MAAM,CAAU,KAAK,GAAG,IAAI,UAAU,CAAC;QACrC,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE;QACxB,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE;KACzB,CAAC,CAAC;CACJ;AAED,+EAA+E;AAC/E,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,WAAW,CAAe,4BAA4B,CAAC,CAC9F,cAAc,EACd;IACE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC1D,SAAS,EAAE,MAAM,CAAC,WAAW;CAC9B,CACF;CAAG;AAEJ,qFAAqF;AACrF,MAAM,OAAO,kBAAmB,SAAQ,MAAM,CAAC,WAAW,CACxD,kCAAkC,CACnC,CAAC,oBAAoB,EAAE;IACtB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC1D,SAAS,EAAE,MAAM,CAAC,WAAW;CAC9B,CAAC;CAAG;AAEL,yFAAyF;AACzF,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAG5E,qFAAqF;AACrF,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,CAC3D,qCAAqC,CACtC,CAAC,uBAAuB,EAAE;IACzB,MAAM,EAAE,UAAU;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;IAC7C,+FAA+F;IAC/F,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAClD,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAC7D;CACF,CAAC;CAAG;AAEL,yFAAyF;AACzF,MAAM,OAAO,iBAAkB,SAAQ,MAAM,CAAC,WAAW,CACvD,iCAAiC,CAClC,CAAC,mBAAmB,EAAE;IACrB,MAAM,EAAE,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC;IAChC,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC,OAAO;IACvB,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;IAC7C,+FAA+F;IAC/F,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAClD,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAC7D;CACF,CAAC;CAAG;AAEL,wFAAwF;AACxF,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
/** A repository label name as returned by GitHub, preserved without case conversion. */
|
|
3
|
+
export declare const RepositoryLabelName: Schema.brand<Schema.NonEmptyString, "GitHubRepositoryLabelName">;
|
|
4
|
+
export type RepositoryLabelName = typeof RepositoryLabelName.Type;
|
|
5
|
+
/** GitHub stores label colors as six hex digits without the leading hash. */
|
|
6
|
+
export declare const RepositoryLabelColor: Schema.brand<Schema.String, "GitHubRepositoryLabelColor">;
|
|
7
|
+
export type RepositoryLabelColor = typeof RepositoryLabelColor.Type;
|
|
8
|
+
declare const RepositoryLabel_base: Schema.Class<RepositoryLabel, Schema.Struct<{
|
|
9
|
+
readonly name: Schema.brand<Schema.NonEmptyString, "GitHubRepositoryLabelName">;
|
|
10
|
+
readonly color: Schema.brand<Schema.String, "GitHubRepositoryLabelColor">;
|
|
11
|
+
readonly description: Schema.OptionFromNullOr<Schema.String>;
|
|
12
|
+
}>, {}>;
|
|
13
|
+
/** One repository label as GitHub defines it. The name routes lanes, and color and description are presentation only. */
|
|
14
|
+
export declare class RepositoryLabel extends RepositoryLabel_base {
|
|
15
|
+
}
|
|
16
|
+
declare const RepositoryLabelCatalog_base: Schema.Class<RepositoryLabelCatalog, Schema.Struct<{
|
|
17
|
+
readonly entityTag: Schema.OptionFromNullOr<Schema.brand<Schema.NonEmptyString, "GitHubEntityTag">>;
|
|
18
|
+
readonly labels: Schema.$Array<typeof RepositoryLabel>;
|
|
19
|
+
}>, {}>;
|
|
20
|
+
/** A complete label catalog with the ETag of its canonical REST URL. */
|
|
21
|
+
export declare class RepositoryLabelCatalog extends RepositoryLabelCatalog_base {
|
|
22
|
+
}
|
|
23
|
+
declare const RepositoryLabelsNotModified_base: Schema.Class<RepositoryLabelsNotModified, Schema.TaggedStruct<"RepositoryLabelsNotModified", {}>, {}>;
|
|
24
|
+
/** GitHub confirmed the catalog named by its ETag has not changed. */
|
|
25
|
+
export declare class RepositoryLabelsNotModified extends RepositoryLabelsNotModified_base {
|
|
26
|
+
}
|
|
27
|
+
/** A complete label catalog or confirmation that the cached catalog is unchanged. */
|
|
28
|
+
export declare const RepositoryLabelDetection: Schema.Union<readonly [typeof RepositoryLabelCatalog, typeof RepositoryLabelsNotModified]>;
|
|
29
|
+
export type RepositoryLabelDetection = typeof RepositoryLabelDetection.Type;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=labels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"labels.d.ts","sourceRoot":"","sources":["../../src/polling/labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,kEAE/B,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAC,IAAI,CAAC;AAElE,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,2DAEiB,CAAC;AACnD,MAAM,MAAM,oBAAoB,GAAG,OAAO,oBAAoB,CAAC,IAAI,CAAC;;;;;;AAEpE,yHAAyH;AACzH,qBAAa,eAAgB,SAAQ,oBAMpC;CAAG;;;;;AAOJ,wEAAwE;AACxE,qBAAa,sBAAuB,SAAQ,2BAK1C;CAAG;;AAEL,sEAAsE;AACtE,qBAAa,2BAA4B,SAAQ,gCAEb;CAAG;AAEvC,qFAAqF;AACrF,eAAO,MAAM,wBAAwB,4FAGnC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,OAAO,wBAAwB,CAAC,IAAI,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { EntityTag } from "./detection.js";
|
|
3
|
+
/** A repository label name as returned by GitHub, preserved without case conversion. */
|
|
4
|
+
export const RepositoryLabelName = Schema.NonEmptyString.pipe(Schema.brand("GitHubRepositoryLabelName"));
|
|
5
|
+
/** GitHub stores label colors as six hex digits without the leading hash. */
|
|
6
|
+
export const RepositoryLabelColor = Schema.String.check(Schema.isPattern(/^[0-9a-fA-F]{6}$/u, { message: "Expected a six-digit hex label color" })).pipe(Schema.brand("GitHubRepositoryLabelColor"));
|
|
7
|
+
/** One repository label as GitHub defines it. The name routes lanes, and color and description are presentation only. */
|
|
8
|
+
export class RepositoryLabel extends Schema.Class("@usine/github/RepositoryLabel")({
|
|
9
|
+
name: RepositoryLabelName,
|
|
10
|
+
color: RepositoryLabelColor,
|
|
11
|
+
description: Schema.OptionFromNullOr(Schema.String),
|
|
12
|
+
}) {
|
|
13
|
+
}
|
|
14
|
+
const uniqueLabelNames = Schema.makeFilter((labels) => new Set(labels.map(({ name }) => name)).size === labels.length, { message: "Expected unique label names" });
|
|
15
|
+
/** A complete label catalog with the ETag of its canonical REST URL. */
|
|
16
|
+
export class RepositoryLabelCatalog extends Schema.Class("@usine/github/RepositoryLabelCatalog")({
|
|
17
|
+
entityTag: Schema.OptionFromNullOr(EntityTag),
|
|
18
|
+
labels: Schema.Array(RepositoryLabel).check(uniqueLabelNames),
|
|
19
|
+
}) {
|
|
20
|
+
}
|
|
21
|
+
/** GitHub confirmed the catalog named by its ETag has not changed. */
|
|
22
|
+
export class RepositoryLabelsNotModified extends Schema.TaggedClass("@usine/github/RepositoryLabelsNotModified")("RepositoryLabelsNotModified", {}) {
|
|
23
|
+
}
|
|
24
|
+
/** A complete label catalog or confirmation that the cached catalog is unchanged. */
|
|
25
|
+
export const RepositoryLabelDetection = Schema.Union([
|
|
26
|
+
RepositoryLabelCatalog,
|
|
27
|
+
RepositoryLabelsNotModified,
|
|
28
|
+
]);
|
|
29
|
+
//# sourceMappingURL=labels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"labels.js","sourceRoot":"","sources":["../../src/polling/labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,wFAAwF;AACxF,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAC3D,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAC1C,CAAC;AAGF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACrD,MAAM,CAAC,SAAS,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,sCAAsC,EAAE,CAAC,CAC3F,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;AAGnD,yHAAyH;AACzH,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,KAAK,CAAkB,+BAA+B,CAAC,CACjG;IACE,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,oBAAoB;IAC3B,WAAW,EAAE,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;CACpD,CACF;CAAG;AAEJ,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CACxC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,EAC1E,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAC3C,CAAC;AAEF,wEAAwE;AACxE,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,KAAK,CACtD,sCAAsC,CACvC,CAAC;IACA,SAAS,EAAE,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC;CAC9D,CAAC;CAAG;AAEL,sEAAsE;AACtE,MAAM,OAAO,2BAA4B,SAAQ,MAAM,CAAC,WAAW,CACjE,2CAA2C,CAC5C,CAAC,6BAA6B,EAAE,EAAE,CAAC;CAAG;AAEvC,qFAAqF;AACrF,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,KAAK,CAAC;IACnD,sBAAsB;IACtB,2BAA2B;CAC5B,CAAC,CAAC"}
|
|
@@ -1,68 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
/**
|
|
3
|
-
* The payload keys that hold a `Timestamp` above. Bound to the slice schemas:
|
|
4
|
-
* a field added to a slice with a `Timestamp` value MUST be listed here, or it
|
|
5
|
-
* silently joins the content hash and re-fires every item once (ADR 0007 keeps
|
|
6
|
-
* timestamps in the payload but out of the hash).
|
|
7
|
-
*/
|
|
8
|
-
export declare const TIMESTAMP_FIELDS: ReadonlySet<string>;
|
|
9
|
-
export declare const EntityTag: Schema.brand<Schema.NonEmptyString, "GitHubEntityTag">;
|
|
10
|
-
export type EntityTag = typeof EntityTag.Type;
|
|
11
|
-
export declare const RepositoryLabelName: Schema.brand<Schema.NonEmptyString, "GitHubRepositoryLabelName">;
|
|
12
|
-
export type RepositoryLabelName = typeof RepositoryLabelName.Type;
|
|
13
|
-
declare const RepositoryLabelCatalog_base: Schema.Class<RepositoryLabelCatalog, Schema.Struct<{
|
|
14
|
-
readonly entityTag: Schema.OptionFromNullOr<Schema.brand<Schema.NonEmptyString, "GitHubEntityTag">>;
|
|
15
|
-
readonly labels: Schema.$Array<Schema.brand<Schema.NonEmptyString, "GitHubRepositoryLabelName">>;
|
|
16
|
-
}>, {}>;
|
|
17
|
-
/** A complete label catalog and the ETag for its canonical REST URL. */
|
|
18
|
-
export declare class RepositoryLabelCatalog extends RepositoryLabelCatalog_base {
|
|
19
|
-
}
|
|
20
|
-
declare const RepositoryLabelsNotModified_base: Schema.Class<RepositoryLabelsNotModified, Schema.TaggedStruct<"RepositoryLabelsNotModified", {}>, {}>;
|
|
21
|
-
/** GitHub confirmed that the catalog named by its ETag has not changed. */
|
|
22
|
-
export declare class RepositoryLabelsNotModified extends RepositoryLabelsNotModified_base {
|
|
23
|
-
}
|
|
24
|
-
export declare const RepositoryLabelDetection: Schema.Union<readonly [typeof RepositoryLabelCatalog, typeof RepositoryLabelsNotModified]>;
|
|
25
|
-
export type RepositoryLabelDetection = typeof RepositoryLabelDetection.Type;
|
|
26
|
-
declare const PollCursor_base: Schema.Class<PollCursor, Schema.Struct<{
|
|
27
|
-
readonly entityTag: Schema.OptionFromNullOr<Schema.brand<Schema.NonEmptyString, "GitHubEntityTag">>;
|
|
28
|
-
readonly watermark: Schema.OptionFromNullOr<Schema.DateTimeUtcFromString>;
|
|
29
|
-
}>, {}>;
|
|
30
|
-
/** Efficiency-only REST cursor. Losing it is safe because Event dedup is permanent. */
|
|
31
|
-
export declare class PollCursor extends PollCursor_base {
|
|
32
|
-
static readonly empty: PollCursor;
|
|
33
|
-
}
|
|
34
|
-
declare const ChangedIssue_base: Schema.Class<ChangedIssue, Schema.TaggedStruct<"ChangedIssue", {
|
|
35
|
-
readonly number: Schema.Int;
|
|
36
|
-
readonly updatedAt: Schema.DateTimeUtc;
|
|
37
|
-
}>, {}>;
|
|
38
|
-
export declare class ChangedIssue extends ChangedIssue_base {
|
|
39
|
-
}
|
|
40
|
-
declare const ChangedPullRequest_base: Schema.Class<ChangedPullRequest, Schema.TaggedStruct<"ChangedPullRequest", {
|
|
41
|
-
readonly number: Schema.Int;
|
|
42
|
-
readonly updatedAt: Schema.DateTimeUtc;
|
|
43
|
-
}>, {}>;
|
|
44
|
-
export declare class ChangedPullRequest extends ChangedPullRequest_base {
|
|
45
|
-
}
|
|
46
|
-
export declare const ChangedItem: Schema.Union<readonly [typeof ChangedIssue, typeof ChangedPullRequest]>;
|
|
47
|
-
export type ChangedItem = typeof ChangedItem.Type;
|
|
48
|
-
declare const RepositoryNotModified_base: Schema.Class<RepositoryNotModified, Schema.TaggedStruct<"RepositoryNotModified", {
|
|
49
|
-
readonly cursor: typeof PollCursor;
|
|
50
|
-
readonly nextPollAt: Schema.Option<Schema.DateTimeUtc>;
|
|
51
|
-
}>, {}>;
|
|
52
|
-
export declare class RepositoryNotModified extends RepositoryNotModified_base {
|
|
53
|
-
}
|
|
54
|
-
declare const RepositoryChanges_base: Schema.Class<RepositoryChanges, Schema.TaggedStruct<"RepositoryChanges", {
|
|
55
|
-
readonly cursor: typeof PollCursor;
|
|
56
|
-
readonly items: Schema.$Array<Schema.Union<readonly [typeof ChangedIssue, typeof ChangedPullRequest]>>;
|
|
57
|
-
/** True when the page cap ended the walk early; the rest arrives next cycle. */
|
|
58
|
-
readonly backlog: Schema.Boolean;
|
|
59
|
-
readonly nextPollAt: Schema.Option<Schema.DateTimeUtc>;
|
|
60
|
-
}>, {}>;
|
|
61
|
-
export declare class RepositoryChanges extends RepositoryChanges_base {
|
|
62
|
-
}
|
|
63
|
-
export declare const ChangeDetection: Schema.Union<readonly [typeof RepositoryNotModified, typeof RepositoryChanges]>;
|
|
64
|
-
export type ChangeDetection = typeof ChangeDetection.Type;
|
|
65
|
-
/** Exact v1 issue payload slice recorded by issue #11. */
|
|
2
|
+
/** The issue payload slice that `if:` expressions and prompt interpolation range over. */
|
|
66
3
|
export declare const IssuePayload: Schema.Struct<{
|
|
67
4
|
readonly number: Schema.Int;
|
|
68
5
|
readonly title: Schema.String;
|
|
@@ -154,7 +91,7 @@ export declare const IssuePayload: Schema.Struct<{
|
|
|
154
91
|
}, never, never>>, never, never>;
|
|
155
92
|
}>;
|
|
156
93
|
export type IssuePayload = typeof IssuePayload.Type;
|
|
157
|
-
/**
|
|
94
|
+
/** The pull-request payload slice that `if:` expressions and prompt interpolation range over. */
|
|
158
95
|
export declare const PullRequestPayload: Schema.Struct<{
|
|
159
96
|
readonly number: Schema.Int;
|
|
160
97
|
readonly title: Schema.String;
|
|
@@ -336,6 +273,7 @@ export declare const PullRequestPayload: Schema.Struct<{
|
|
|
336
273
|
}, never, never>>, never, never>;
|
|
337
274
|
}>;
|
|
338
275
|
export type PullRequestPayload = typeof PullRequestPayload.Type;
|
|
276
|
+
/** Identifies an Item's payload content for Event deduplication; timestamp-only changes keep the same hash. */
|
|
339
277
|
export declare const ContentHash: Schema.brand<Schema.String, "GitHubContentHash">;
|
|
340
278
|
export type ContentHash = typeof ContentHash.Type;
|
|
341
279
|
declare const IssueSnapshot_base: Schema.Class<IssueSnapshot, Schema.TaggedStruct<"IssueSnapshot", {
|
|
@@ -431,6 +369,7 @@ declare const IssueSnapshot_base: Schema.Class<IssueSnapshot, Schema.TaggedStruc
|
|
|
431
369
|
}>;
|
|
432
370
|
readonly contentHash: Schema.brand<Schema.String, "GitHubContentHash">;
|
|
433
371
|
}>, {}>;
|
|
372
|
+
/** An issue's observed payload and the content identity used to decide whether it represents new work. */
|
|
434
373
|
export declare class IssueSnapshot extends IssueSnapshot_base {
|
|
435
374
|
}
|
|
436
375
|
declare const PullRequestSnapshot_base: Schema.Class<PullRequestSnapshot, Schema.TaggedStruct<"PullRequestSnapshot", {
|
|
@@ -616,9 +555,11 @@ declare const PullRequestSnapshot_base: Schema.Class<PullRequestSnapshot, Schema
|
|
|
616
555
|
}>;
|
|
617
556
|
readonly contentHash: Schema.brand<Schema.String, "GitHubContentHash">;
|
|
618
557
|
}>, {}>;
|
|
558
|
+
/** A pull request's observed payload and the content identity used to decide whether it represents new work. */
|
|
619
559
|
export declare class PullRequestSnapshot extends PullRequestSnapshot_base {
|
|
620
560
|
}
|
|
561
|
+
/** The fetched Item state shared by selection, prompt rendering, and Event deduplication. */
|
|
621
562
|
export declare const PayloadSnapshot: Schema.Union<readonly [typeof IssueSnapshot, typeof PullRequestSnapshot]>;
|
|
622
563
|
export type PayloadSnapshot = typeof PayloadSnapshot.Type;
|
|
623
564
|
export {};
|
|
624
|
-
//# sourceMappingURL=
|
|
565
|
+
//# sourceMappingURL=payload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../src/polling/payload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,QAAQ,CAAC;AA8C9C,0FAA0F;AAC1F,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BvB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAC;AAiBpD,iGAAiG;AACjG,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsD7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC,IAAI,CAAC;AAEhE,+GAA+G;AAC/G,eAAO,MAAM,WAAW,kDAEiB,CAAC;AAC1C,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAElD,0GAA0G;AAC1G,qBAAa,aAAc,SAAQ,kBAMlC;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEJ,gHAAgH;AAChH,qBAAa,mBAAoB,SAAQ,wBAKvC;CAAG;AAEL,6FAA6F;AAC7F,eAAO,MAAM,eAAe,2EAAqD,CAAC;AAClF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAC"}
|
|
@@ -1,77 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Schema, SchemaGetter } from "effect";
|
|
2
2
|
const PositiveInt = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1));
|
|
3
3
|
const NonNegativeInt = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
|
|
4
4
|
const Timestamp = Schema.String.check(Schema.isPattern(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/u, {
|
|
5
5
|
message: "Expected a GitHub UTC timestamp",
|
|
6
6
|
}));
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* timestamps in the payload but out of the hash).
|
|
12
|
-
*/
|
|
13
|
-
export const TIMESTAMP_FIELDS = new Set([
|
|
14
|
-
"closedAt",
|
|
15
|
-
"createdAt",
|
|
16
|
-
"mergedAt",
|
|
17
|
-
"submittedAt",
|
|
18
|
-
"updatedAt",
|
|
19
|
-
]);
|
|
20
|
-
export const EntityTag = Schema.NonEmptyString.pipe(Schema.brand("GitHubEntityTag"));
|
|
21
|
-
export const RepositoryLabelName = Schema.NonEmptyString.pipe(Schema.brand("GitHubRepositoryLabelName"));
|
|
22
|
-
/** A complete label catalog and the ETag for its canonical REST URL. */
|
|
23
|
-
export class RepositoryLabelCatalog extends Schema.Class("@usine/github/RepositoryLabelCatalog")({
|
|
24
|
-
entityTag: Schema.OptionFromNullOr(EntityTag),
|
|
25
|
-
labels: Schema.Array(RepositoryLabelName).check(Schema.isUnique()),
|
|
26
|
-
}) {
|
|
27
|
-
}
|
|
28
|
-
/** GitHub confirmed that the catalog named by its ETag has not changed. */
|
|
29
|
-
export class RepositoryLabelsNotModified extends Schema.TaggedClass("@usine/github/RepositoryLabelsNotModified")("RepositoryLabelsNotModified", {}) {
|
|
30
|
-
}
|
|
31
|
-
export const RepositoryLabelDetection = Schema.Union([
|
|
32
|
-
RepositoryLabelCatalog,
|
|
33
|
-
RepositoryLabelsNotModified,
|
|
34
|
-
]);
|
|
35
|
-
/** Efficiency-only REST cursor. Losing it is safe because Event dedup is permanent. */
|
|
36
|
-
export class PollCursor extends Schema.Class("@usine/github/PollCursor")({
|
|
37
|
-
entityTag: Schema.OptionFromNullOr(EntityTag),
|
|
38
|
-
watermark: Schema.OptionFromNullOr(Schema.DateTimeUtcFromString),
|
|
39
|
-
}) {
|
|
40
|
-
static empty = new PollCursor({
|
|
41
|
-
entityTag: Option.none(),
|
|
42
|
-
watermark: Option.none(),
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
export class ChangedIssue extends Schema.TaggedClass("@usine/github/ChangedIssue")("ChangedIssue", {
|
|
46
|
-
number: PositiveInt,
|
|
47
|
-
updatedAt: Schema.DateTimeUtc,
|
|
48
|
-
}) {
|
|
49
|
-
}
|
|
50
|
-
export class ChangedPullRequest extends Schema.TaggedClass("@usine/github/ChangedPullRequest")("ChangedPullRequest", {
|
|
51
|
-
number: PositiveInt,
|
|
52
|
-
updatedAt: Schema.DateTimeUtc,
|
|
53
|
-
}) {
|
|
54
|
-
}
|
|
55
|
-
export const ChangedItem = Schema.Union([ChangedIssue, ChangedPullRequest]);
|
|
56
|
-
export class RepositoryNotModified extends Schema.TaggedClass("@usine/github/RepositoryNotModified")("RepositoryNotModified", {
|
|
57
|
-
cursor: PollCursor,
|
|
58
|
-
nextPollAt: Schema.Option(Schema.DateTimeUtc),
|
|
59
|
-
}) {
|
|
60
|
-
}
|
|
61
|
-
export class RepositoryChanges extends Schema.TaggedClass("@usine/github/RepositoryChanges")("RepositoryChanges", {
|
|
62
|
-
cursor: PollCursor,
|
|
63
|
-
items: Schema.Array(ChangedItem),
|
|
64
|
-
/** True when the page cap ended the walk early; the rest arrives next cycle. */
|
|
65
|
-
backlog: Schema.Boolean,
|
|
66
|
-
nextPollAt: Schema.Option(Schema.DateTimeUtc),
|
|
67
|
-
}) {
|
|
68
|
-
}
|
|
69
|
-
export const ChangeDetection = Schema.Union([RepositoryNotModified, RepositoryChanges]);
|
|
70
|
-
/**
|
|
71
|
-
* GitHub declares most GraphQL connections nullable. A null connection and an
|
|
72
|
-
* empty one carry the same information, so the boundary normalizes null to
|
|
73
|
-
* empty — the domain type (and the CEL environment typed on it) stays
|
|
74
|
-
* non-null, and both shapes hash identically.
|
|
8
|
+
* GitHub declares most GraphQL connections nullable, and a null connection means
|
|
9
|
+
* the same as an empty one. Decoding null to empty keeps the payload type
|
|
10
|
+
* non-null and hashes both shapes identically.
|
|
75
11
|
*/
|
|
76
12
|
const orEmpty = (schema, empty) => Schema.NullOr(schema).pipe(Schema.decodeTo(schema, {
|
|
77
13
|
decode: SchemaGetter.transform((value) => value ?? empty),
|
|
@@ -91,7 +27,7 @@ const IssueComments = Schema.Struct({
|
|
|
91
27
|
totalCount: NonNegativeInt,
|
|
92
28
|
nodes: Schema.Array(IssueComment),
|
|
93
29
|
});
|
|
94
|
-
/**
|
|
30
|
+
/** The issue payload slice that `if:` expressions and prompt interpolation range over. */
|
|
95
31
|
export const IssuePayload = Schema.Struct({
|
|
96
32
|
number: PositiveInt,
|
|
97
33
|
title: Schema.String,
|
|
@@ -118,7 +54,7 @@ export const IssuePayload = Schema.Struct({
|
|
|
118
54
|
})),
|
|
119
55
|
}), emptyConnection),
|
|
120
56
|
});
|
|
121
|
-
/** Null when the reviewer is a deleted user or a mannequin
|
|
57
|
+
/** Null when the reviewer is a deleted user or a mannequin. That null is real content and stays in the payload. */
|
|
122
58
|
const RequestedReviewer = Schema.NullOr(Schema.Struct({ login: Schema.optionalKey(Schema.NonEmptyString) }));
|
|
123
59
|
const Review = Schema.Struct({
|
|
124
60
|
author: NullableActor,
|
|
@@ -128,7 +64,7 @@ const Review = Schema.Struct({
|
|
|
128
64
|
commit: Schema.NullOr(Schema.Struct({ oid: Schema.NonEmptyString })),
|
|
129
65
|
});
|
|
130
66
|
const ReviewThreadComment = Schema.Struct({ author: NullableActor, body: Schema.String });
|
|
131
|
-
/**
|
|
67
|
+
/** The pull-request payload slice that `if:` expressions and prompt interpolation range over. */
|
|
132
68
|
export const PullRequestPayload = Schema.Struct({
|
|
133
69
|
number: PositiveInt,
|
|
134
70
|
title: Schema.String,
|
|
@@ -173,16 +109,20 @@ export const PullRequestPayload = Schema.Struct({
|
|
|
173
109
|
nodes: Schema.Array(Schema.Struct({ number: PositiveInt, state: Schema.String })),
|
|
174
110
|
}), emptyConnection),
|
|
175
111
|
});
|
|
112
|
+
/** Identifies an Item's payload content for Event deduplication; timestamp-only changes keep the same hash. */
|
|
176
113
|
export const ContentHash = Schema.String.check(Schema.isPattern(/^[a-f0-9]{64}$/u, { message: "Expected a SHA-256 content hash" })).pipe(Schema.brand("GitHubContentHash"));
|
|
114
|
+
/** An issue's observed payload and the content identity used to decide whether it represents new work. */
|
|
177
115
|
export class IssueSnapshot extends Schema.TaggedClass("@usine/github/IssueSnapshot")("IssueSnapshot", {
|
|
178
116
|
payload: IssuePayload,
|
|
179
117
|
contentHash: ContentHash,
|
|
180
118
|
}) {
|
|
181
119
|
}
|
|
120
|
+
/** A pull request's observed payload and the content identity used to decide whether it represents new work. */
|
|
182
121
|
export class PullRequestSnapshot extends Schema.TaggedClass("@usine/github/PullRequestSnapshot")("PullRequestSnapshot", {
|
|
183
122
|
payload: PullRequestPayload,
|
|
184
123
|
contentHash: ContentHash,
|
|
185
124
|
}) {
|
|
186
125
|
}
|
|
126
|
+
/** The fetched Item state shared by selection, prompt rendering, and Event deduplication. */
|
|
187
127
|
export const PayloadSnapshot = Schema.Union([IssueSnapshot, PullRequestSnapshot]);
|
|
188
|
-
//# sourceMappingURL=
|
|
128
|
+
//# sourceMappingURL=payload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../../src/polling/payload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE9C,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvE,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;AAE1E,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACnC,MAAM,CAAC,SAAS,CAAC,mDAAmD,EAAE;IACpE,OAAO,EAAE,iCAAiC;CAC3C,CAAC,CACH,CAAC;AAEF;;;;GAIG;AACH,MAAM,OAAO,GAAG,CAAI,MAAwC,EAAE,KAAQ,EAAE,EAAE,CACxE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CACxB,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE;IACtB,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,KAAe,EAAE,EAAE,CAAC,KAAK,IAAI,KAAK,CAAC;IACnE,MAAM,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,KAAQ,EAAE,EAAE,CAAC,KAAK,CAAC;CACpD,CAAC,CACH,CAAC;AAEJ,MAAM,eAAe,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAW,CAAC;AAE9D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;AAE9D,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAE3C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;AAE7D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAEzF,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,MAAM,EAAE,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,SAAS,EAAE,SAAS;CACrB,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;IAClC,UAAU,EAAE,cAAc;IAC1B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC;CAClC,CAAC,CAAC;AAEH,0FAA0F;AAC1F,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,GAAG,EAAE,MAAM,CAAC,cAAc;IAC1B,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IACzC,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;IAClC,MAAM,EAAE,aAAa;IACrB,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAChE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACjE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;IACpF,QAAQ,EAAE,aAAa;IACvB,8BAA8B,EAAE,OAAO,CACrC,MAAM,CAAC,MAAM,CAAC;QACZ,UAAU,EAAE,cAAc;QAC1B,KAAK,EAAE,MAAM,CAAC,KAAK,CACjB,MAAM,CAAC,MAAM,CAAC;YACZ,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,GAAG,EAAE,MAAM,CAAC,cAAc;SAC3B,CAAC,CACH;KACF,CAAC,EACF,eAAe,CAChB;CACF,CAAC,CAAC;AAGH,mHAAmH;AACnH,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CACrC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CACpE,CAAC;AAEF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3B,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;CACrE,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAE1F,iGAAiG;AACjG,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9C,MAAM,EAAE,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,GAAG,EAAE,MAAM,CAAC,cAAc;IAC1B,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,OAAO,EAAE,MAAM,CAAC,OAAO;IACvB,MAAM,EAAE,MAAM,CAAC,OAAO;IACtB,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;IAClC,MAAM,EAAE,aAAa;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM;IAC1B,WAAW,EAAE,MAAM,CAAC,MAAM;IAC1B,UAAU,EAAE,MAAM,CAAC,cAAc;IACjC,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,cAAc;IACzB,YAAY,EAAE,cAAc;IAC5B,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5C,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACzE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC;IACxC,cAAc,EAAE,OAAO,CACrB,MAAM,CAAC,MAAM,CAAC;QACZ,UAAU,EAAE,cAAc;QAC1B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,CAAC,CAAC;KAC7E,CAAC,EACF,eAAe,CAChB;IACD,OAAO,EAAE,OAAO,CACd,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAC1E,eAAe,CAChB;IACD,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC;QAC3B,UAAU,EAAE,cAAc;QAC1B,KAAK,EAAE,MAAM,CAAC,KAAK,CACjB,MAAM,CAAC,MAAM,CAAC;YACZ,UAAU,EAAE,MAAM,CAAC,OAAO;YAC1B,UAAU,EAAE,MAAM,CAAC,OAAO;YAC1B,IAAI,EAAE,MAAM,CAAC,MAAM;YACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;gBACtB,UAAU,EAAE,cAAc;gBAC1B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC;aACzC,CAAC;SACH,CAAC,CACH;KACF,CAAC;IACF,QAAQ,EAAE,aAAa;IACvB,uBAAuB,EAAE,OAAO,CAC9B,MAAM,CAAC,MAAM,CAAC;QACZ,UAAU,EAAE,cAAc;QAC1B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;KAClF,CAAC,EACF,eAAe,CAChB;CACF,CAAC,CAAC;AAGH,+GAA+G;AAC/G,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAC5C,MAAM,CAAC,SAAS,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC,CACpF,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;AAG1C,0GAA0G;AAC1G,MAAM,OAAO,aAAc,SAAQ,MAAM,CAAC,WAAW,CAAgB,6BAA6B,CAAC,CACjG,eAAe,EACf;IACE,OAAO,EAAE,YAAY;IACrB,WAAW,EAAE,WAAW;CACzB,CACF;CAAG;AAEJ,gHAAgH;AAChH,MAAM,OAAO,mBAAoB,SAAQ,MAAM,CAAC,WAAW,CACzD,mCAAmC,CACpC,CAAC,qBAAqB,EAAE;IACvB,OAAO,EAAE,kBAAkB;IAC3B,WAAW,EAAE,WAAW;CACzB,CAAC;CAAG;AAEL,6FAA6F;AAC7F,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC,CAAC"}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RepositoryName } from "@usine/core/repository";
|
|
2
2
|
import { Context, Crypto, Effect, Layer, Option } from "effect";
|
|
3
3
|
import { HttpClient } from "effect/unstable/http";
|
|
4
4
|
import { GitHubApp } from "../github-app.ts";
|
|
5
|
-
import { type GitHubAppError } from "../
|
|
6
|
-
import { EntityTag, PollCursor,
|
|
5
|
+
import { type GitHubAppError } from "../error.ts";
|
|
6
|
+
import { EntityTag, PollCursor, type ChangeDetection, type ChangedItem } from "./detection.ts";
|
|
7
|
+
import { type PayloadSnapshot } from "./payload.ts";
|
|
8
|
+
import { RepositoryLabelCatalog, RepositoryLabelsNotModified } from "./labels.ts";
|
|
7
9
|
declare const GitHubPolling_base: Context.ServiceClass<GitHubPolling, "@usine/github/GitHubPolling", {
|
|
8
|
-
|
|
9
|
-
readonly
|
|
10
|
-
|
|
10
|
+
/** Finds issue and PR updates since the saved cursor; persist the returned cursor after processing the detected Items. */
|
|
11
|
+
readonly changes: (repository: RepositoryName, cursor: PollCursor) => Effect.Effect<ChangeDetection, GitHubAppError>;
|
|
12
|
+
/** Reads the repository's label catalog, or confirms the catalog named by `entityTag` is unchanged. */
|
|
13
|
+
readonly labels: (repository: RepositoryName, entityTag: Option.Option<EntityTag>) => Effect.Effect<RepositoryLabelCatalog | RepositoryLabelsNotModified, GitHubAppError>;
|
|
14
|
+
/** Fetches an Item's selection and prompt payload together with its timestamp-independent content hash. */
|
|
15
|
+
readonly snapshot: (repository: RepositoryName, item: ChangedItem) => Effect.Effect<PayloadSnapshot, GitHubAppError>;
|
|
11
16
|
}>;
|
|
12
|
-
/** GitHub
|
|
17
|
+
/** Finds changed GitHub Items and fetches the snapshots used to select work for Loops. */
|
|
13
18
|
export declare class GitHubPolling extends GitHubPolling_base {
|
|
14
|
-
/** Live GitHub polling adapter over an installation token and Effect HTTP. */
|
|
15
19
|
static readonly layer: Layer.Layer<GitHubPolling, never, Crypto.Crypto | GitHubApp | HttpClient.HttpClient>;
|
|
16
20
|
}
|
|
17
|
-
export {};
|
|
21
|
+
export { EntityTag, PollCursor, ChangedIssue, ChangedPullRequest, ChangedItem, RepositoryNotModified, RepositoryChanges, ChangeDetection, } from "./detection.ts";
|
|
22
|
+
export { RepositoryLabelName, RepositoryLabelColor, RepositoryLabel, RepositoryLabelCatalog, RepositoryLabelsNotModified, RepositoryLabelDetection, } from "./labels.ts";
|
|
23
|
+
export { ContentHash, IssuePayload, PullRequestPayload, IssueSnapshot, PullRequestSnapshot, PayloadSnapshot, } from "./payload.ts";
|
|
18
24
|
//# sourceMappingURL=polling.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/polling/polling.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/polling/polling.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAuB,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAS,OAAO,EAAE,MAAM,EAAY,MAAM,EAAE,KAAK,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACzF,OAAO,EAAE,UAAU,EAAyC,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAY7C,OAAO,EAAwB,KAAK,cAAc,EAAwB,MAAM,aAAa,CAAC;AAC9F,OAAO,EAGL,SAAS,EACT,UAAU,EAGV,KAAK,eAAe,EACpB,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAML,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,sBAAsB,EAEtB,2BAA2B,EAE5B,MAAM,aAAa,CAAC;;IAkJjB,0HAA0H;sBACxG,CAChB,UAAU,EAAE,cAAc,EAC1B,MAAM,EAAE,UAAU,KACf,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,cAAc,CAAC;IACnD,uGAAuG;qBACtF,CACf,UAAU,EAAE,cAAc,EAC1B,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAChC,MAAM,CAAC,MAAM,CAAC,sBAAsB,GAAG,2BAA2B,EAAE,cAAc,CAAC;IACxF,2GAA2G;uBACxF,CACjB,UAAU,EAAE,cAAc,EAC1B,IAAI,EAAE,WAAW,KACd,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,cAAc,CAAC;;AAlBvD,0FAA0F;AAC1F,qBAAa,aAAc,SAAQ,kBAmBD;IAChC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAChC,aAAa,EACb,KAAK,EACL,MAAM,CAAC,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,UAAU,CAClD,CAsTC;CACH;AAED,OAAO,EACL,SAAS,EACT,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,eAAe,GAChB,MAAM,cAAc,CAAC"}
|
package/dist/polling/polling.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { canonicalContent } from "./content.js";
|
|
2
|
+
import { RepositoryName, splitRepositoryName } from "@usine/core/repository";
|
|
2
3
|
import { Clock, Context, Crypto, DateTime, Effect, Layer, Option, Schema } from "effect";
|
|
3
4
|
import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http";
|
|
4
5
|
import { GitHubApp } from "../github-app.js";
|
|
5
6
|
import { API_ROOT, authorized, invalidResponse, pollIntervalMillis, rateLimitResetMillis, rateLimitRetryEpoch, retryAfterMillis, statusError, transportError, } from "../http.js";
|
|
6
|
-
import { GitHubRateLimitError } from "../
|
|
7
|
-
import { ChangedIssue, ChangedPullRequest,
|
|
7
|
+
import { GitHubRateLimitError } from "../error.js";
|
|
8
|
+
import { ChangedIssue, ChangedPullRequest, EntityTag, PollCursor, RepositoryChanges, RepositoryNotModified, } from "./detection.js";
|
|
9
|
+
import { ContentHash, IssuePayload, IssueSnapshot, PullRequestPayload, PullRequestSnapshot, } from "./payload.js";
|
|
10
|
+
import { RepositoryLabel, RepositoryLabelCatalog, RepositoryLabelColor, RepositoryLabelsNotModified, RepositoryLabelName, } from "./labels.js";
|
|
8
11
|
import { ISSUE_PAYLOAD_QUERY, PULL_REQUEST_PAYLOAD_QUERY } from "./queries.js";
|
|
9
12
|
const WATERMARK_OVERLAP_MS = 5_000;
|
|
10
13
|
const RATE_LIMIT_PRESSURE_THRESHOLD = 100;
|
|
11
|
-
/**
|
|
14
|
+
/** Caps one cycle's REST walk. The watermark resumes the remainder next cycle. */
|
|
12
15
|
const MAX_CHANGE_PAGES = 10;
|
|
13
|
-
/**
|
|
16
|
+
/** Caps one repository's label walk so a pathological catalog cannot run unbounded. */
|
|
14
17
|
const MAX_LABEL_PAGES = 100;
|
|
15
|
-
/** GraphQL rate limiting sometimes omits reset headers
|
|
18
|
+
/** GraphQL rate limiting sometimes omits reset headers. Wait at least this long then. */
|
|
16
19
|
const GRAPHQL_RATE_LIMIT_FALLBACK_MS = 60_000;
|
|
17
20
|
const RestChangedItem = Schema.Struct({
|
|
18
21
|
number: Schema.Int.check(Schema.isGreaterThanOrEqualTo(1)),
|
|
@@ -20,8 +23,13 @@ const RestChangedItem = Schema.Struct({
|
|
|
20
23
|
pullRequest: Schema.optionalKey(Schema.Unknown),
|
|
21
24
|
}).pipe(Schema.encodeKeys({ updatedAt: "updated_at", pullRequest: "pull_request" }));
|
|
22
25
|
const RestChangedItems = Schema.Array(RestChangedItem);
|
|
23
|
-
const RestRepositoryLabels = Schema.Array(Schema.Struct({
|
|
24
|
-
|
|
26
|
+
const RestRepositoryLabels = Schema.Array(Schema.Struct({
|
|
27
|
+
name: RepositoryLabelName,
|
|
28
|
+
color: RepositoryLabelColor,
|
|
29
|
+
description: Schema.NullOr(Schema.String),
|
|
30
|
+
}));
|
|
31
|
+
const catalogLabel = ({ name, color, description, }) => new RepositoryLabel({ name, color, description: Option.fromNullishOr(description) });
|
|
32
|
+
/** The GraphQL transport envelope. `errors` arrives on HTTP 200 and must be read. */
|
|
25
33
|
const GraphqlEnvelope = Schema.Struct({
|
|
26
34
|
data: Schema.optionalKey(Schema.Unknown),
|
|
27
35
|
errors: Schema.optionalKey(Schema.Array(Schema.Struct({
|
|
@@ -35,17 +43,6 @@ const IssueData = Schema.Struct({
|
|
|
35
43
|
const PullRequestData = Schema.Struct({
|
|
36
44
|
repository: Schema.OptionFromNullOr(Schema.Struct({ pullRequest: Schema.OptionFromNullOr(PullRequestPayload) })),
|
|
37
45
|
});
|
|
38
|
-
const canonicalContent = (value) => {
|
|
39
|
-
if (Array.isArray(value))
|
|
40
|
-
return value.map(canonicalContent);
|
|
41
|
-
if (Schema.is(Schema.JsonObject)(value)) {
|
|
42
|
-
return Object.fromEntries(Object.entries(value)
|
|
43
|
-
.filter(([key]) => !TIMESTAMP_FIELDS.has(key))
|
|
44
|
-
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
45
|
-
.map(([key, child]) => [key, canonicalContent(child)]));
|
|
46
|
-
}
|
|
47
|
-
return value;
|
|
48
|
-
};
|
|
49
46
|
const dateTimeAt = (epochMillis) => DateTime.make(epochMillis);
|
|
50
47
|
const toChangedItems = (decoded) => decoded.map((item) => item.pullRequest === undefined
|
|
51
48
|
? new ChangedIssue({ number: item.number, updatedAt: item.updatedAt })
|
|
@@ -56,12 +53,16 @@ const latestDateTime = (candidates) => {
|
|
|
56
53
|
return Option.none();
|
|
57
54
|
return dateTimeAt(Math.max(...epochs));
|
|
58
55
|
};
|
|
56
|
+
const requestBackoff = (headers, now) => latestDateTime([
|
|
57
|
+
retryAfterMillis(headers["retry-after"], now),
|
|
58
|
+
rateLimitResetMillis(headers, RATE_LIMIT_PRESSURE_THRESHOLD),
|
|
59
|
+
]);
|
|
59
60
|
const nextPollAt = (headers, now) => latestDateTime([
|
|
60
61
|
pollIntervalMillis(headers, now),
|
|
61
62
|
retryAfterMillis(headers["retry-after"], now),
|
|
62
63
|
rateLimitResetMillis(headers, RATE_LIMIT_PRESSURE_THRESHOLD),
|
|
63
64
|
]);
|
|
64
|
-
/**
|
|
65
|
+
/** The `rel="next"` URL from a Link header when GitHub has more pages. */
|
|
65
66
|
const nextPageUrl = (link) => {
|
|
66
67
|
if (link === undefined)
|
|
67
68
|
return Option.none();
|
|
@@ -73,7 +74,7 @@ const sinceParameter = (watermark) => {
|
|
|
73
74
|
return `${new Date(epoch - (epoch % 1_000)).toISOString().slice(0, 19)}Z`;
|
|
74
75
|
};
|
|
75
76
|
const changesUrl = (repository, cursor) => {
|
|
76
|
-
const { name, owner } =
|
|
77
|
+
const { name, owner } = splitRepositoryName(repository);
|
|
77
78
|
const url = new URL(`${API_ROOT}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/issues`);
|
|
78
79
|
url.searchParams.set("state", "all");
|
|
79
80
|
url.searchParams.set("sort", "updated");
|
|
@@ -85,13 +86,13 @@ const changesUrl = (repository, cursor) => {
|
|
|
85
86
|
return url.toString();
|
|
86
87
|
};
|
|
87
88
|
const labelsUrl = (repository) => {
|
|
88
|
-
const { name, owner } =
|
|
89
|
+
const { name, owner } = splitRepositoryName(repository);
|
|
89
90
|
const url = new URL(`${API_ROOT}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/labels`);
|
|
90
91
|
url.searchParams.set("per_page", "100");
|
|
91
92
|
return url.toString();
|
|
92
93
|
};
|
|
93
94
|
const itemLabelsUrl = (repository, item) => {
|
|
94
|
-
const { name, owner } =
|
|
95
|
+
const { name, owner } = splitRepositoryName(repository);
|
|
95
96
|
const url = new URL(`${API_ROOT}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/issues/${item}/labels`);
|
|
96
97
|
url.searchParams.set("per_page", "100");
|
|
97
98
|
return url.toString();
|
|
@@ -103,16 +104,8 @@ const newerWatermark = (cursor, items) => {
|
|
|
103
104
|
}
|
|
104
105
|
return epochs.length === 0 ? Option.none() : dateTimeAt(Math.max(...epochs));
|
|
105
106
|
};
|
|
106
|
-
|
|
107
|
-
const encoded = new TextEncoder().encode(JSON.stringify(canonicalContent(payload)));
|
|
108
|
-
// An in-memory SHA-256 digest cannot fail for expected reasons: a failure
|
|
109
|
-
// here is a violated platform invariant, not a domain failure.
|
|
110
|
-
const digest = yield* crypto.digest("SHA-256", encoded).pipe(Effect.orDie);
|
|
111
|
-
return ContentHash.make(Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join(""));
|
|
112
|
-
});
|
|
113
|
-
/** GitHub change detection and snapshot fetching behind one external seam. */
|
|
107
|
+
/** Finds changed GitHub Items and fetches the snapshots used to select work for Loops. */
|
|
114
108
|
export class GitHubPolling extends Context.Service()("@usine/github/GitHubPolling") {
|
|
115
|
-
/** Live GitHub polling adapter over an installation token and Effect HTTP. */
|
|
116
109
|
static layer = Layer.effect(GitHubPolling, Effect.gen(function* () {
|
|
117
110
|
const app = yield* GitHubApp;
|
|
118
111
|
const crypto = yield* Crypto.Crypto;
|
|
@@ -147,11 +140,11 @@ export class GitHubPolling extends Context.Service()("@usine/github/GitHubPollin
|
|
|
147
140
|
}
|
|
148
141
|
const decoded = yield* HttpClientResponse.schemaBodyJson(RestRepositoryLabels)(response).pipe(Effect.mapError((error) => invalidResponse(operation, error.message)));
|
|
149
142
|
return {
|
|
150
|
-
labels: decoded.map(
|
|
143
|
+
labels: decoded.map(catalogLabel),
|
|
151
144
|
next: nextPageUrl(response.headers.link),
|
|
152
145
|
};
|
|
153
146
|
});
|
|
154
|
-
/** Walks the pages after an already-fetched first
|
|
147
|
+
/** Walks the label pages after an already-fetched first page, under the label page cap. */
|
|
155
148
|
const remainingLabelPages = Effect.fn("GitHubPolling.remainingLabelPages")(function* (operation, firstPage) {
|
|
156
149
|
const catalog = [...firstPage.labels];
|
|
157
150
|
let next = firstPage.next;
|
|
@@ -165,7 +158,7 @@ export class GitHubPolling extends Context.Service()("@usine/github/GitHubPollin
|
|
|
165
158
|
if (Option.isSome(next)) {
|
|
166
159
|
return yield* invalidResponse(operation, `GitHub label list exceeded ${MAX_LABEL_PAGES} pages`);
|
|
167
160
|
}
|
|
168
|
-
return catalog.sort((left, right) => left.localeCompare(right));
|
|
161
|
+
return catalog.sort((left, right) => left.name.localeCompare(right.name));
|
|
169
162
|
});
|
|
170
163
|
const allLabels = Effect.fn("GitHubPolling.allLabels")(function* (operation, initialUrl) {
|
|
171
164
|
return yield* remainingLabelPages(operation, yield* labelsPage(operation, initialUrl));
|
|
@@ -186,7 +179,7 @@ export class GitHubPolling extends Context.Service()("@usine/github/GitHubPollin
|
|
|
186
179
|
}
|
|
187
180
|
const firstPage = yield* HttpClientResponse.schemaBodyJson(RestRepositoryLabels)(response).pipe(Effect.mapError((error) => invalidResponse("list-repository-labels", error.message)));
|
|
188
181
|
const catalog = yield* remainingLabelPages("list-repository-labels", {
|
|
189
|
-
labels: firstPage.map(
|
|
182
|
+
labels: firstPage.map(catalogLabel),
|
|
190
183
|
next: nextPageUrl(response.headers.link),
|
|
191
184
|
});
|
|
192
185
|
const catalogEntityTag = Schema.decodeUnknownOption(EntityTag)(response.headers.etag);
|
|
@@ -207,16 +200,19 @@ export class GitHubPolling extends Context.Service()("@usine/github/GitHubPollin
|
|
|
207
200
|
const now = yield* Clock.currentTimeMillis;
|
|
208
201
|
const recommended = nextPollAt(response.headers, now);
|
|
209
202
|
if (response.status === 304) {
|
|
210
|
-
return new RepositoryNotModified({
|
|
203
|
+
return new RepositoryNotModified({
|
|
204
|
+
cursor,
|
|
205
|
+
nextPollAt: recommended,
|
|
206
|
+
backoffUntil: requestBackoff(response.headers, now),
|
|
207
|
+
});
|
|
211
208
|
}
|
|
212
209
|
if (response.status !== 200) {
|
|
213
210
|
return yield* statusError("poll-repository-changes", response, now);
|
|
214
211
|
}
|
|
215
212
|
const decoded = yield* HttpClientResponse.schemaBodyJson(RestChangedItems)(response).pipe(Effect.mapError((error) => invalidResponse("poll-repository-changes", error.message)));
|
|
216
213
|
const items = toChangedItems(decoded);
|
|
217
|
-
// The ETag is efficiency
|
|
218
|
-
//
|
|
219
|
-
// matches the canonical URL the next cycle re-requests.
|
|
214
|
+
// The ETag is efficiency only: a page without one costs conditional requests next cycle, never correctness.
|
|
215
|
+
// Only the first page's tag matches the canonical URL the next cycle re-requests.
|
|
220
216
|
const entityTag = Schema.decodeUnknownOption(EntityTag)(response.headers.etag);
|
|
221
217
|
if (Option.isNone(entityTag)) {
|
|
222
218
|
yield* Effect.logWarning("GitHub omitted the changes ETag; next poll is unconditional", {
|
|
@@ -245,19 +241,19 @@ export class GitHubPolling extends Context.Service()("@usine/github/GitHubPollin
|
|
|
245
241
|
items: allItems,
|
|
246
242
|
backlog,
|
|
247
243
|
nextPollAt: recommended,
|
|
244
|
+
backoffUntil: requestBackoff(response.headers, now),
|
|
248
245
|
});
|
|
249
246
|
});
|
|
250
247
|
const graphql = Effect.fn("GitHubPolling.graphql")(function* (operation, repository, number, query, dataSchema) {
|
|
251
248
|
const token = yield* app.installationToken();
|
|
252
|
-
const { name, owner } =
|
|
249
|
+
const { name, owner } = splitRepositoryName(repository);
|
|
253
250
|
const request = HttpClientRequest.post(`${API_ROOT}/graphql`).pipe(HttpClientRequest.bodyJsonUnsafe({ query, variables: { owner, name, number } }), authorized(token.value));
|
|
254
251
|
const response = yield* execute(operation, request);
|
|
255
252
|
const now = yield* Clock.currentTimeMillis;
|
|
256
253
|
if (response.status !== 200)
|
|
257
254
|
return yield* statusError(operation, response, now);
|
|
258
255
|
const envelope = yield* HttpClientResponse.schemaBodyJson(GraphqlEnvelope)(response).pipe(Effect.mapError((error) => invalidResponse(operation, error.message)));
|
|
259
|
-
// GraphQL reports failures on HTTP 200
|
|
260
|
-
// wait; anything else keeps its messages for diagnosis.
|
|
256
|
+
// GraphQL reports failures on HTTP 200. Rate limiting becomes a typed wait, and anything else keeps its messages for diagnosis.
|
|
261
257
|
if (envelope.errors !== undefined && envelope.errors.length > 0) {
|
|
262
258
|
const rateLimited = envelope.errors.some((error) => error.type === "RATE_LIMITED");
|
|
263
259
|
if (rateLimited) {
|
|
@@ -283,7 +279,7 @@ export class GitHubPolling extends Context.Service()("@usine/github/GitHubPollin
|
|
|
283
279
|
totalLabels: payload.labels.totalCount,
|
|
284
280
|
});
|
|
285
281
|
const names = yield* allLabels("fetch-item-labels", itemLabelsUrl(repository, item.number));
|
|
286
|
-
return { totalCount: names.length, nodes: names.map((name) => ({ name })) };
|
|
282
|
+
return { totalCount: names.length, nodes: names.map(({ name }) => ({ name })) };
|
|
287
283
|
});
|
|
288
284
|
if (item._tag === "ChangedIssue") {
|
|
289
285
|
const data = yield* graphql("fetch-issue-snapshot", repository, item.number, ISSUE_PAYLOAD_QUERY, IssueData);
|
|
@@ -317,4 +313,13 @@ export class GitHubPolling extends Context.Service()("@usine/github/GitHubPollin
|
|
|
317
313
|
return { changes, labels, snapshot };
|
|
318
314
|
}));
|
|
319
315
|
}
|
|
316
|
+
export { EntityTag, PollCursor, ChangedIssue, ChangedPullRequest, ChangedItem, RepositoryNotModified, RepositoryChanges, ChangeDetection, } from "./detection.js";
|
|
317
|
+
export { RepositoryLabelName, RepositoryLabelColor, RepositoryLabel, RepositoryLabelCatalog, RepositoryLabelsNotModified, RepositoryLabelDetection, } from "./labels.js";
|
|
318
|
+
export { ContentHash, IssuePayload, PullRequestPayload, IssueSnapshot, PullRequestSnapshot, PayloadSnapshot, } from "./payload.js";
|
|
319
|
+
const makeContentHash = (crypto) => Effect.fn("GitHubPolling.contentHash")(function* (payload) {
|
|
320
|
+
const encoded = new TextEncoder().encode(JSON.stringify(canonicalContent(payload)));
|
|
321
|
+
// An in-memory SHA-256 digest fails only on a broken platform, so a failure here is a defect.
|
|
322
|
+
const digest = yield* crypto.digest("SHA-256", encoded).pipe(Effect.orDie);
|
|
323
|
+
return ContentHash.make(Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join(""));
|
|
324
|
+
});
|
|
320
325
|
//# sourceMappingURL=polling.js.map
|