@shivaedev/github 0.0.0 → 0.6.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.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +238 -1
  3. package/dist/GitHub.d.ts +93 -0
  4. package/dist/GitHub.d.ts.map +1 -0
  5. package/dist/GitHub.js +53 -0
  6. package/dist/GitHub.js.map +1 -0
  7. package/dist/GitHubConfig.d.ts +6 -0
  8. package/dist/GitHubConfig.d.ts.map +1 -0
  9. package/dist/GitHubConfig.js +5 -0
  10. package/dist/GitHubConfig.js.map +1 -0
  11. package/dist/GitHubToken.d.ts +9 -0
  12. package/dist/GitHubToken.d.ts.map +1 -0
  13. package/dist/GitHubToken.js +8 -0
  14. package/dist/GitHubToken.js.map +1 -0
  15. package/dist/TokenRefresh.d.ts +5 -0
  16. package/dist/TokenRefresh.d.ts.map +1 -0
  17. package/dist/TokenRefresh.js +5 -0
  18. package/dist/TokenRefresh.js.map +1 -0
  19. package/dist/appJwt.d.ts +8 -0
  20. package/dist/appJwt.d.ts.map +1 -0
  21. package/dist/appJwt.js +16 -0
  22. package/dist/appJwt.js.map +1 -0
  23. package/dist/artifacts.d.ts +16 -0
  24. package/dist/artifacts.d.ts.map +1 -0
  25. package/dist/artifacts.js +31 -0
  26. package/dist/artifacts.js.map +1 -0
  27. package/dist/authenticatedRequest.d.ts +8 -0
  28. package/dist/authenticatedRequest.d.ts.map +1 -0
  29. package/dist/authenticatedRequest.js +42 -0
  30. package/dist/authenticatedRequest.js.map +1 -0
  31. package/dist/cache.d.ts +12 -0
  32. package/dist/cache.d.ts.map +1 -0
  33. package/dist/cache.js +17 -0
  34. package/dist/cache.js.map +1 -0
  35. package/dist/checkRuns.d.ts +104 -0
  36. package/dist/checkRuns.d.ts.map +1 -0
  37. package/dist/checkRuns.js +42 -0
  38. package/dist/checkRuns.js.map +1 -0
  39. package/dist/errors.d.ts +44 -0
  40. package/dist/errors.d.ts.map +1 -0
  41. package/dist/errors.js +35 -0
  42. package/dist/errors.js.map +1 -0
  43. package/dist/githubApp.d.ts +24 -0
  44. package/dist/githubApp.d.ts.map +1 -0
  45. package/dist/githubApp.js +55 -0
  46. package/dist/githubApp.js.map +1 -0
  47. package/dist/json.d.ts +7 -0
  48. package/dist/json.d.ts.map +1 -0
  49. package/dist/json.js +14 -0
  50. package/dist/json.js.map +1 -0
  51. package/dist/markdown.d.ts +4 -0
  52. package/dist/markdown.d.ts.map +1 -0
  53. package/dist/markdown.js +24 -0
  54. package/dist/markdown.js.map +1 -0
  55. package/dist/markdownRows.d.ts +6 -0
  56. package/dist/markdownRows.d.ts.map +1 -0
  57. package/dist/markdownRows.js +26 -0
  58. package/dist/markdownRows.js.map +1 -0
  59. package/dist/rateLimits.d.ts +20 -0
  60. package/dist/rateLimits.d.ts.map +1 -0
  61. package/dist/rateLimits.js +43 -0
  62. package/dist/rateLimits.js.map +1 -0
  63. package/dist/representations.d.ts +18 -0
  64. package/dist/representations.d.ts.map +1 -0
  65. package/dist/representations.js +28 -0
  66. package/dist/representations.js.map +1 -0
  67. package/dist/requests.d.ts +10 -0
  68. package/dist/requests.d.ts.map +1 -0
  69. package/dist/requests.js +34 -0
  70. package/dist/requests.js.map +1 -0
  71. package/dist/status.d.ts +7 -0
  72. package/dist/status.d.ts.map +1 -0
  73. package/dist/status.js +57 -0
  74. package/dist/status.js.map +1 -0
  75. package/dist/stickyComments.d.ts +46 -0
  76. package/dist/stickyComments.d.ts.map +1 -0
  77. package/dist/stickyComments.js +37 -0
  78. package/dist/stickyComments.js.map +1 -0
  79. package/dist/verifyWebhook.d.ts +4 -0
  80. package/dist/verifyWebhook.d.ts.map +1 -0
  81. package/dist/verifyWebhook.js +14 -0
  82. package/dist/verifyWebhook.js.map +1 -0
  83. package/package.json +71 -4
  84. package/src/GitHub.ts +68 -0
  85. package/src/GitHubConfig.ts +5 -0
  86. package/src/GitHubToken.ts +16 -0
  87. package/src/TokenRefresh.ts +7 -0
  88. package/src/appJwt.ts +21 -0
  89. package/src/artifacts.ts +57 -0
  90. package/src/authenticatedRequest.ts +55 -0
  91. package/src/cache.ts +25 -0
  92. package/src/checkRuns.ts +48 -0
  93. package/src/errors.ts +34 -0
  94. package/src/githubApp.ts +87 -0
  95. package/src/json.ts +16 -0
  96. package/src/markdown.ts +25 -0
  97. package/src/markdownRows.ts +30 -0
  98. package/src/rateLimits.ts +56 -0
  99. package/src/representations.ts +57 -0
  100. package/src/requests.ts +44 -0
  101. package/src/status.ts +64 -0
  102. package/src/stickyComments.ts +49 -0
  103. package/src/verifyWebhook.ts +19 -0
@@ -0,0 +1,8 @@
1
+ import { Effect } from "effect";
2
+ import { type HttpClient, type HttpClientError, HttpClientRequest } from "effect/http";
3
+ import { GitHubTransportError } from "./errors.ts";
4
+ import type { GitHubToken } from "./GitHubToken.ts";
5
+ import { type RateLimits } from "./rateLimits.ts";
6
+ import type { TokenRefresh } from "./TokenRefresh.ts";
7
+ export declare function authenticatedRequest<R>(client: HttpClient.HttpClient.With<HttpClientError.HttpClientError, R>, token: GitHubToken["Service"], rates: RateLimits, refresh?: typeof TokenRefresh.Service): (input: HttpClientRequest.HttpClientRequest, mode?: "manual" | "revalidate" | undefined) => Effect.Effect<import("effect/http/HttpClientResponse").HttpClientResponse, import("./errors.ts").GitHubAppError | import("./errors.ts").GitHubConversationLocked | import("./errors.ts").GitHubPermissionDenied | import("./errors.ts").GitHubRateLimited | GitHubTransportError | import("@shivaedev/http/errors.ts").ResponseBodyTooLarge | import("@shivaedev/http/errors.ts").RemoteStatusError, R>;
8
+ //# sourceMappingURL=authenticatedRequest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticatedRequest.d.ts","sourceRoot":"","sources":["../src/authenticatedRequest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAoB,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAmB,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACxG,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,wBAAgB,oBAAoB,CAAC,CAAC,EACrC,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,eAAe,EAAE,CAAC,CAAC,EACtE,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,EAC7B,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,OAAO,YAAY,CAAC,OAAmB,ueAqChD"}
@@ -0,0 +1,42 @@
1
+ import { DateTime, Effect, Option, Redacted } from "effect";
2
+ import { FetchHttpClient, HttpClientRequest } from "effect/http";
3
+ import { GitHubTransportError } from "./errors.js";
4
+ import { failRateLimited } from "./rateLimits.js";
5
+ import { checkStatus, isUnauthorized, isUnchanged } from "./status.js";
6
+ export function authenticatedRequest(client, token, rates, refresh = undefined) {
7
+ const accessToken = Effect.isEffect(token) ? token : Effect.succeed(token);
8
+ return Effect.fnUntraced(function* (input, mode) {
9
+ const path = new URL(input.url).pathname;
10
+ const resource = rates.resource(path);
11
+ const blocked = rates.blocked.get(resource);
12
+ if (blocked !== undefined && DateTime.isGreaterThan(blocked.retryAt, yield* DateTime.now)) {
13
+ return yield* failRateLimited(path, blocked, rates.observations.get(resource)?.remaining);
14
+ }
15
+ function send(current) {
16
+ const sent = client.execute(withCredential(input, current));
17
+ return (mode === "manual" ? sent.pipe(Effect.provideService(FetchHttpClient.RequestInit, { credentials: "omit", redirect: "manual" })) : sent).pipe(Effect.mapError(() => new GitHubTransportError({ path })));
18
+ }
19
+ const credential = yield* accessToken;
20
+ let response = yield* send(credential);
21
+ if (isUnauthorized(response) && refresh !== undefined) {
22
+ yield* refresh(credential);
23
+ response = yield* send(yield* accessToken);
24
+ }
25
+ const observedResource = rates.observe(response);
26
+ if (!((mode === "revalidate" && isUnchanged(response)) || (mode === "manual" && response.status === 302))) {
27
+ yield* checkStatus(response, observedResource, rates.failures.get(observedResource) ?? 0).pipe(Effect.catchTag("HttpClientError", () => Effect.fail(new GitHubTransportError({ path }))), Effect.catchTag("GitHubRateLimited", (error) => {
28
+ rates.blocked.set(error.resource, error);
29
+ rates.failures.set(error.resource, (rates.failures.get(error.resource) ?? 0) + 1);
30
+ return failRateLimited(path, error, rates.observations.get(error.resource)?.remaining);
31
+ }));
32
+ }
33
+ rates.failures.delete(observedResource);
34
+ rates.blocked.delete(observedResource);
35
+ return response;
36
+ });
37
+ }
38
+ function withCredential(input, credential) {
39
+ const request = HttpClientRequest.setHeader(input, "X-GitHub-Api-Version", "2022-11-28");
40
+ return Option.isSome(credential) ? HttpClientRequest.setHeader(request, "Authorization", `Bearer ${Redacted.value(credential.value)}`) : request;
41
+ }
42
+ //# sourceMappingURL=authenticatedRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticatedRequest.js","sourceRoot":"","sources":["../src/authenticatedRequest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAyC,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACxG,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAmB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGvE,MAAM,UAAU,oBAAoB,CACnC,MAAsE,EACtE,KAA6B,EAC7B,KAAiB,EACjB,OAAO,GAAgC,SAAS;IAEhD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3E,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,KAA0C,EAAE,IAA8B;QAC7G,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,SAAS,IAAI,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3F,OAAO,KAAK,CAAC,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;QAC3F,CAAC;QACD,SAAS,IAAI,CAAC,OAAiD;YAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;YAC5D,OAAO,CACN,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,WAAW,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CACrI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;QACtC,IAAI,QAAQ,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACvD,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC3B,QAAQ,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;YAC3G,KAAK,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC7F,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EACzF,MAAM,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC9C,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;gBACzC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAClF,OAAO,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;YACxF,CAAC,CAAC,CACF,CAAC;QACH,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACxC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACvC,OAAO,QAAQ,CAAC;IACjB,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAA0C,EAAE,UAAoD;IACvH,MAAM,OAAO,GAAG,iBAAiB,CAAC,SAAS,CAAC,KAAK,EAAE,sBAAsB,EAAE,YAAY,CAAC,CAAC;IACzF,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,UAAU,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAClJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Schema } from "effect";
2
+ import type { HttpClientResponse } from "effect/http";
3
+ export interface CachedResponse {
4
+ readonly bytes: Uint8Array;
5
+ readonly decoded: Map<Schema.Constraint, unknown>;
6
+ readonly response: HttpClientResponse.HttpClientResponse;
7
+ }
8
+ export declare function responseCache(): {
9
+ get: (key: string) => CachedResponse | undefined;
10
+ set(key: string, entry: CachedResponse): void;
11
+ };
12
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAClD,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC,kBAAkB,CAAC;CACzD;AAED,wBAAgB,aAAa;IAG3B,GAAG,QAAQ,MAAM;IACjB,GAAG,MAAM,MAAM,SAAS,cAAc;EAWvC"}
package/dist/cache.js ADDED
@@ -0,0 +1,17 @@
1
+ export function responseCache() {
2
+ const entries = new Map();
3
+ return {
4
+ get: (key) => entries.get(key),
5
+ set(key, entry) {
6
+ entries.delete(key);
7
+ entries.set(key, entry);
8
+ if (entries.size > 1000) {
9
+ const first = entries.keys().next();
10
+ if (!first.done) {
11
+ entries.delete(first.value);
12
+ }
13
+ }
14
+ },
15
+ };
16
+ }
17
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,aAAa;IAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAClD,OAAO;QACN,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;QACtC,GAAG,CAAC,GAAW,EAAE,KAAqB;YACrC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACxB,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;gBACpC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;oBACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC7B,CAAC;YACF,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,104 @@
1
+ import { Effect, Schema } from "effect";
2
+ import type { Representations } from "./representations.ts";
3
+ export declare const CheckRunOutput: Schema.Struct<{
4
+ readonly summary: Schema.String;
5
+ readonly text: Schema.optional<Schema.String>;
6
+ readonly title: Schema.String;
7
+ }>;
8
+ export declare const CheckRunConclusion: Schema.Literals<readonly ["action_required", "cancelled", "failure", "neutral", "success", "skipped", "stale", "timed_out"]>;
9
+ export declare const CheckRunStatus: Schema.Literals<readonly ["queued", "in_progress", "completed"]>;
10
+ export declare const CreateCheckRun: Schema.encodeKeys<Schema.Struct<{
11
+ readonly conclusion: Schema.optional<Schema.Literals<readonly ["action_required", "cancelled", "failure", "neutral", "success", "skipped", "stale", "timed_out"]>>;
12
+ readonly headSha: Schema.String;
13
+ readonly name: Schema.String;
14
+ readonly output: Schema.optional<Schema.Struct<{
15
+ readonly summary: Schema.String;
16
+ readonly text: Schema.optional<Schema.String>;
17
+ readonly title: Schema.String;
18
+ }>>;
19
+ readonly status: Schema.Literals<readonly ["queued", "in_progress", "completed"]>;
20
+ }>, {
21
+ readonly headSha: "head_sha";
22
+ }>;
23
+ export declare const UpdateCheckRun: Schema.Union<readonly [Schema.Struct<{
24
+ readonly output: Schema.optional<Schema.Struct<{
25
+ readonly summary: Schema.String;
26
+ readonly text: Schema.optional<Schema.String>;
27
+ readonly title: Schema.String;
28
+ }>>;
29
+ readonly status: Schema.Literals<readonly ["queued", "in_progress"]>;
30
+ }>, Schema.Struct<{
31
+ readonly conclusion: Schema.Literals<readonly ["action_required", "cancelled", "failure", "neutral", "success", "skipped", "stale", "timed_out"]>;
32
+ readonly output: Schema.optional<Schema.Struct<{
33
+ readonly summary: Schema.String;
34
+ readonly text: Schema.optional<Schema.String>;
35
+ readonly title: Schema.String;
36
+ }>>;
37
+ readonly status: Schema.Literal<"completed">;
38
+ }>]>;
39
+ export declare const CheckRun: Schema.encodeKeys<Schema.Struct<{
40
+ readonly conclusion: Schema.NullOr<Schema.Literals<readonly ["action_required", "cancelled", "failure", "neutral", "success", "skipped", "stale", "timed_out"]>>;
41
+ readonly headSha: Schema.String;
42
+ readonly id: Schema.Number;
43
+ readonly name: Schema.String;
44
+ readonly output: Schema.Struct<{
45
+ readonly summary: Schema.NullOr<Schema.String>;
46
+ readonly text: Schema.NullOr<Schema.String>;
47
+ readonly title: Schema.NullOr<Schema.String>;
48
+ }>;
49
+ readonly status: Schema.Literals<readonly ["queued", "in_progress", "completed"]>;
50
+ }>, {
51
+ readonly headSha: "head_sha";
52
+ }>;
53
+ export declare function checkRuns(client: Representations): {
54
+ createCheckRun: (owner: string, repo: string, input: {
55
+ readonly conclusion?: "action_required" | "cancelled" | "failure" | "neutral" | "skipped" | "stale" | "success" | "timed_out" | undefined;
56
+ readonly headSha: string;
57
+ readonly name: string;
58
+ readonly output?: {
59
+ readonly summary: string;
60
+ readonly text?: string | undefined;
61
+ readonly title: string;
62
+ } | undefined;
63
+ readonly status: "completed" | "in_progress" | "queued";
64
+ }) => Effect.Effect<{
65
+ readonly conclusion: "action_required" | "cancelled" | "failure" | "neutral" | "skipped" | "stale" | "success" | "timed_out" | null;
66
+ readonly headSha: string;
67
+ readonly id: number;
68
+ readonly name: string;
69
+ readonly output: {
70
+ readonly summary: string | null;
71
+ readonly text: string | null;
72
+ readonly title: string | null;
73
+ };
74
+ readonly status: "completed" | "in_progress" | "queued";
75
+ }, import("./errors.ts").GitHubAppError | import("./errors.ts").GitHubConversationLocked | import("./errors.ts").GitHubPermissionDenied | import("./errors.ts").GitHubRateLimited | import("./errors.ts").GitHubTransportError | import("effect/http/HttpBody").HttpBodyError | import("@shivaedev/http/errors.ts").ResponseBodyTooLarge | Schema.SchemaError | import("@shivaedev/http/errors.ts").RemoteStatusError, never>;
76
+ updateCheckRun: (owner: string, repo: string, id: number, input: {
77
+ readonly output?: {
78
+ readonly summary: string;
79
+ readonly text?: string | undefined;
80
+ readonly title: string;
81
+ } | undefined;
82
+ readonly status: "in_progress" | "queued";
83
+ } | {
84
+ readonly conclusion: "action_required" | "cancelled" | "failure" | "neutral" | "skipped" | "stale" | "success" | "timed_out";
85
+ readonly output?: {
86
+ readonly summary: string;
87
+ readonly text?: string | undefined;
88
+ readonly title: string;
89
+ } | undefined;
90
+ readonly status: "completed";
91
+ }) => Effect.Effect<{
92
+ readonly conclusion: "action_required" | "cancelled" | "failure" | "neutral" | "skipped" | "stale" | "success" | "timed_out" | null;
93
+ readonly headSha: string;
94
+ readonly id: number;
95
+ readonly name: string;
96
+ readonly output: {
97
+ readonly summary: string | null;
98
+ readonly text: string | null;
99
+ readonly title: string | null;
100
+ };
101
+ readonly status: "completed" | "in_progress" | "queued";
102
+ }, import("./errors.ts").GitHubAppError | import("./errors.ts").GitHubConversationLocked | import("./errors.ts").GitHubPermissionDenied | import("./errors.ts").GitHubRateLimited | import("./errors.ts").GitHubTransportError | import("effect/http/HttpBody").HttpBodyError | import("@shivaedev/http/errors.ts").ResponseBodyTooLarge | Schema.SchemaError | import("@shivaedev/http/errors.ts").RemoteStatusError, never>;
103
+ };
104
+ //# sourceMappingURL=checkRuns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkRuns.d.ts","sourceRoot":"","sources":["../src/checkRuns.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,eAAO,MAAM,cAAc;;;;EAIzB,CAAC;AAEH,eAAO,MAAM,kBAAkB,8HAAsH,CAAC;AACtJ,eAAO,MAAM,cAAc,kEAA0D,CAAC;AAEtF,eAAO,MAAM,cAAc;;;;;;;;;;;;EAMwB,CAAC;AAEpD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;IAGzB,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;EAO8B,CAAC;AAEpD,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe;IAE/C,cAAc;;;;;;;;;;;;;;;;;;;;;;IAKd,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMf"}
@@ -0,0 +1,42 @@
1
+ import { Effect, Schema } from "effect";
2
+ export const CheckRunOutput = Schema.Struct({
3
+ summary: Schema.String,
4
+ text: Schema.optional(Schema.String),
5
+ title: Schema.String,
6
+ });
7
+ export const CheckRunConclusion = Schema.Literals(["action_required", "cancelled", "failure", "neutral", "success", "skipped", "stale", "timed_out"]);
8
+ export const CheckRunStatus = Schema.Literals(["queued", "in_progress", "completed"]);
9
+ export const CreateCheckRun = Schema.Struct({
10
+ conclusion: Schema.optional(CheckRunConclusion),
11
+ headSha: Schema.String,
12
+ name: Schema.String,
13
+ output: Schema.optional(CheckRunOutput),
14
+ status: CheckRunStatus,
15
+ }).pipe(Schema.encodeKeys({ headSha: "head_sha" }));
16
+ export const UpdateCheckRun = Schema.Union([
17
+ Schema.Struct({ output: Schema.optional(CheckRunOutput), status: Schema.Literals(["queued", "in_progress"]) }),
18
+ Schema.Struct({ conclusion: CheckRunConclusion, output: Schema.optional(CheckRunOutput), status: Schema.Literal("completed") }),
19
+ ]);
20
+ export const CheckRun = Schema.Struct({
21
+ conclusion: Schema.NullOr(CheckRunConclusion),
22
+ headSha: Schema.String,
23
+ id: Schema.Number,
24
+ name: Schema.String,
25
+ output: Schema.Struct({ summary: Schema.NullOr(Schema.String), text: Schema.NullOr(Schema.String), title: Schema.NullOr(Schema.String) }),
26
+ status: CheckRunStatus,
27
+ }).pipe(Schema.encodeKeys({ headSha: "head_sha" }));
28
+ export function checkRuns(client) {
29
+ return {
30
+ createCheckRun: Effect.fn("GitHub.createCheckRun")(function* (owner, repo, input) {
31
+ const body = yield* Schema.encodeEffect(CreateCheckRun)(input);
32
+ const response = yield* client.write("POST", `/repos/${owner}/${repo}/check-runs`, body);
33
+ return yield* response.decode(CheckRun);
34
+ }),
35
+ updateCheckRun: Effect.fn("GitHub.updateCheckRun")(function* (owner, repo, id, input) {
36
+ const body = yield* Schema.encodeEffect(UpdateCheckRun)(input);
37
+ const response = yield* client.write("PATCH", `/repos/${owner}/${repo}/check-runs/${id}`, body);
38
+ return yield* response.decode(CheckRun);
39
+ }),
40
+ };
41
+ }
42
+ //# sourceMappingURL=checkRuns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkRuns.js","sourceRoot":"","sources":["../src/checkRuns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { Schema } from "effect";
2
+ declare const GitHubPermissionDenied_base: Schema.Class<GitHubPermissionDenied, Schema.TaggedStruct<"GitHubPermissionDenied", {
3
+ readonly path: Schema.String;
4
+ }>, import("effect/Cause").YieldableError>;
5
+ export declare class GitHubPermissionDenied extends GitHubPermissionDenied_base {
6
+ }
7
+ declare const GitHubConversationLocked_base: Schema.Class<GitHubConversationLocked, Schema.TaggedStruct<"GitHubConversationLocked", {
8
+ readonly path: Schema.String;
9
+ }>, import("effect/Cause").YieldableError>;
10
+ export declare class GitHubConversationLocked extends GitHubConversationLocked_base {
11
+ }
12
+ declare const GitHubRateLimited_base: Schema.Class<GitHubRateLimited, Schema.TaggedStruct<"GitHubRateLimited", {
13
+ readonly resource: Schema.String;
14
+ readonly retryAt: Schema.DateTimeUtc;
15
+ }>, import("effect/Cause").YieldableError>;
16
+ export declare class GitHubRateLimited extends GitHubRateLimited_base {
17
+ }
18
+ declare const GitHubTransportError_base: Schema.Class<GitHubTransportError, Schema.TaggedStruct<"GitHubTransportError", {
19
+ readonly path: Schema.String;
20
+ }>, import("effect/Cause").YieldableError>;
21
+ export declare class GitHubTransportError extends GitHubTransportError_base {
22
+ }
23
+ declare const GitHubAppError_base: Schema.Class<GitHubAppError, Schema.TaggedStruct<"GitHubAppError", {
24
+ readonly stage: Schema.Literals<readonly ["sign", "exchange"]>;
25
+ readonly status: Schema.optional<Schema.Number>;
26
+ }>, import("effect/Cause").YieldableError>;
27
+ export declare class GitHubAppError extends GitHubAppError_base {
28
+ }
29
+ declare const GitHubWebhookSignatureError_base: Schema.Class<GitHubWebhookSignatureError, Schema.TaggedStruct<"GitHubWebhookSignatureError", {}>, import("effect/Cause").YieldableError>;
30
+ export declare class GitHubWebhookSignatureError extends GitHubWebhookSignatureError_base {
31
+ }
32
+ declare const GitHubArtifactError_base: Schema.Class<GitHubArtifactError, Schema.TaggedStruct<"GitHubArtifactError", {
33
+ readonly stage: Schema.Literals<readonly ["redirect", "download"]>;
34
+ readonly status: Schema.Number;
35
+ }>, import("effect/Cause").YieldableError>;
36
+ export declare class GitHubArtifactError extends GitHubArtifactError_base {
37
+ }
38
+ declare const GitHubArtifactTooLarge_base: Schema.Class<GitHubArtifactTooLarge, Schema.TaggedStruct<"GitHubArtifactTooLarge", {
39
+ readonly limit: Schema.Number;
40
+ }>, import("effect/Cause").YieldableError>;
41
+ export declare class GitHubArtifactTooLarge extends GitHubArtifactTooLarge_base {
42
+ }
43
+ export {};
44
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;AAEhC,qBAAa,sBAAuB,SAAQ,2BAE1C;CAAG;;;;AAEL,qBAAa,wBAAyB,SAAQ,6BAE5C;CAAG;;;;;AAEL,qBAAa,iBAAkB,SAAQ,sBAGrC;CAAG;;;;AAEL,qBAAa,oBAAqB,SAAQ,yBAExC;CAAG;;;;;AAEL,qBAAa,cAAe,SAAQ,mBAGlC;CAAG;;AAEL,qBAAa,2BAA4B,SAAQ,gCAAoF;CAAG;;;;;AAExI,qBAAa,mBAAoB,SAAQ,wBAGvC;CAAG;;;;AAEL,qBAAa,sBAAuB,SAAQ,2BAE1C;CAAG"}
package/dist/errors.js ADDED
@@ -0,0 +1,35 @@
1
+ import { Schema } from "effect";
2
+ export class GitHubPermissionDenied extends Schema.TaggedError()("GitHubPermissionDenied", {
3
+ path: Schema.String,
4
+ }) {
5
+ }
6
+ export class GitHubConversationLocked extends Schema.TaggedError()("GitHubConversationLocked", {
7
+ path: Schema.String,
8
+ }) {
9
+ }
10
+ export class GitHubRateLimited extends Schema.TaggedError()("GitHubRateLimited", {
11
+ resource: Schema.String,
12
+ retryAt: Schema.DateTimeUtc,
13
+ }) {
14
+ }
15
+ export class GitHubTransportError extends Schema.TaggedError()("GitHubTransportError", {
16
+ path: Schema.String,
17
+ }) {
18
+ }
19
+ export class GitHubAppError extends Schema.TaggedError()("GitHubAppError", {
20
+ stage: Schema.Literals(["sign", "exchange"]),
21
+ status: Schema.optional(Schema.Number),
22
+ }) {
23
+ }
24
+ export class GitHubWebhookSignatureError extends Schema.TaggedError()("GitHubWebhookSignatureError", {}) {
25
+ }
26
+ export class GitHubArtifactError extends Schema.TaggedError()("GitHubArtifactError", {
27
+ stage: Schema.Literals(["redirect", "download"]),
28
+ status: Schema.Number,
29
+ }) {
30
+ }
31
+ export class GitHubArtifactTooLarge extends Schema.TaggedError()("GitHubArtifactTooLarge", {
32
+ limit: Schema.Number,
33
+ }) {
34
+ }
35
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,WAAW,EAA0B,CAAC,wBAAwB,EAAE;IAClH,IAAI,EAAE,MAAM,CAAC,MAAM;CACnB,CAAC;CAAG;AAEL,MAAM,OAAO,wBAAyB,SAAQ,MAAM,CAAC,WAAW,EAA4B,CAAC,0BAA0B,EAAE;IACxH,IAAI,EAAE,MAAM,CAAC,MAAM;CACnB,CAAC;CAAG;AAEL,MAAM,OAAO,iBAAkB,SAAQ,MAAM,CAAC,WAAW,EAAqB,CAAC,mBAAmB,EAAE;IACnG,QAAQ,EAAE,MAAM,CAAC,MAAM;IACvB,OAAO,EAAE,MAAM,CAAC,WAAW;CAC3B,CAAC;CAAG;AAEL,MAAM,OAAO,oBAAqB,SAAQ,MAAM,CAAC,WAAW,EAAwB,CAAC,sBAAsB,EAAE;IAC5G,IAAI,EAAE,MAAM,CAAC,MAAM;CACnB,CAAC;CAAG;AAEL,MAAM,OAAO,cAAe,SAAQ,MAAM,CAAC,WAAW,EAAkB,CAAC,gBAAgB,EAAE;IAC1F,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CAAC;CAAG;AAEL,MAAM,OAAO,2BAA4B,SAAQ,MAAM,CAAC,WAAW,EAA+B,CAAC,6BAA6B,EAAE,EAAE,CAAC;CAAG;AAExI,MAAM,OAAO,mBAAoB,SAAQ,MAAM,CAAC,WAAW,EAAuB,CAAC,qBAAqB,EAAE;IACzG,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAChD,MAAM,EAAE,MAAM,CAAC,MAAM;CACrB,CAAC;CAAG;AAEL,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,WAAW,EAA0B,CAAC,wBAAwB,EAAE;IAClH,KAAK,EAAE,MAAM,CAAC,MAAM;CACpB,CAAC;CAAG"}
@@ -0,0 +1,24 @@
1
+ import { Layer } from "effect";
2
+ import { HttpClient } from "effect/http";
3
+ import { type AppCredentials } from "#appJwt.ts";
4
+ import { GitHubToken } from "#GitHubToken.ts";
5
+ export interface InstallationScope {
6
+ readonly permissions?: Readonly<Record<string, "read" | "write" | "admin">>;
7
+ readonly repositories?: readonly string[];
8
+ readonly repositoryIds?: readonly number[];
9
+ }
10
+ export type GitHubAppOptions = AppCredentials & ({
11
+ readonly installationId: number;
12
+ readonly scope?: InstallationScope;
13
+ } | {
14
+ readonly owner: string;
15
+ readonly repository: string;
16
+ readonly scope?: InstallationScope;
17
+ } | {
18
+ readonly installationId?: never;
19
+ readonly owner?: never;
20
+ readonly repository?: never;
21
+ readonly scope?: never;
22
+ });
23
+ export declare function githubApp(options: GitHubAppOptions): Layer.Layer<GitHubToken, never, HttpClient.HttpClient>;
24
+ //# sourceMappingURL=githubApp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubApp.d.ts","sourceRoot":"","sources":["../src/githubApp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,EAA4B,MAAM,QAAQ,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,KAAK,cAAc,EAAU,MAAM,YAAY,CAAC;AAGzD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAC5E,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAC5C,CACG;IAAE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAAE,GAC3F;IAAE,QAAQ,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAClH,CAAC;AAOH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,0DAqClD"}
@@ -0,0 +1,55 @@
1
+ import { Cache, Clock, Context, Effect, Exit, Layer, Option, Redacted, Schema } from "effect";
2
+ import { HttpClient, HttpClientRequest } from "effect/http";
3
+ import { readBoundedJson } from "@shivaedev/http/body.ts";
4
+ import { appJwt } from "#appJwt.ts";
5
+ import { GitHubAppError } from "#errors.ts";
6
+ import { GitHubConfig } from "#GitHubConfig.ts";
7
+ import { GitHubToken } from "#GitHubToken.ts";
8
+ import { TokenRefresh } from "#TokenRefresh.ts";
9
+ const Installation = Schema.Struct({ id: Schema.Number });
10
+ const AccessToken = Schema.Struct({ expiresAt: Schema.DateFromString, token: Schema.RedactedFromValue(Schema.String) }).pipe(Schema.encodeKeys({ expiresAt: "expires_at" }));
11
+ export function githubApp(options) {
12
+ return Layer.effectContext(Effect.gen(function* () {
13
+ if (!("installationId" in options || "owner" in options)) {
14
+ return Context.make(GitHubToken, Effect.map(appJwt(options), Option.some)).pipe(Context.add(TokenRefresh, undefined));
15
+ }
16
+ const client = yield* HttpClient.HttpClient;
17
+ const { apiUrl } = yield* GitHubConfig;
18
+ const clock = yield* Clock.Clock;
19
+ let installationId = "installationId" in options ? options.installationId : undefined;
20
+ const request = appRequests(client, apiUrl);
21
+ const exchange = Effect.gen(function* () {
22
+ const jwt = yield* appJwt(options);
23
+ if (installationId === undefined && "owner" in options && options.owner !== undefined) {
24
+ const path = `/repos/${encodeURIComponent(options.owner)}/${encodeURIComponent(options.repository)}/installation`;
25
+ installationId = (yield* request("GET", path, jwt, Installation)).id;
26
+ }
27
+ return yield* request("POST", `/app/installations/${installationId}/access_tokens`, jwt, AccessToken, {
28
+ permissions: options.scope?.permissions,
29
+ repositories: options.scope?.repositories,
30
+ "repository_ids": options.scope?.repositoryIds,
31
+ });
32
+ });
33
+ const cache = yield* Cache.makeWith((_) => exchange, {
34
+ capacity: 1,
35
+ timeToLive: (exit) => (Exit.isSuccess(exit) ? Math.max(0, exit.value.expiresAt.getTime() - clock.currentTimeMillisUnsafe() - 300_000) : 0),
36
+ });
37
+ return Context.make(GitHubToken, Effect.map(Cache.get(cache, undefined), ({ token }) => Option.some(token))).pipe(Context.add(TokenRefresh, (rejected) => Cache.invalidateWhen(cache, undefined, ({ token }) => Option.isSome(rejected) && token === rejected.value)));
38
+ }));
39
+ }
40
+ function appRequests(client, apiUrl) {
41
+ return Effect.fnUntraced(function* (method, path, jwt, schema, body) {
42
+ let input = HttpClientRequest.make(method)(new URL(path, apiUrl).href, {
43
+ headers: { Accept: "application/vnd.github+json", Authorization: `Bearer ${Redacted.value(jwt)}`, "X-GitHub-Api-Version": "2022-11-28" },
44
+ });
45
+ if (body !== undefined) {
46
+ input = yield* HttpClientRequest.bodyJson(input, body).pipe(Effect.mapError(() => new GitHubAppError({ stage: "exchange" })));
47
+ }
48
+ const response = yield* client.execute(input).pipe(Effect.mapError(() => new GitHubAppError({ stage: "exchange" })));
49
+ if (response.status < 200 || response.status >= 300) {
50
+ return yield* new GitHubAppError({ stage: "exchange", status: response.status });
51
+ }
52
+ return yield* readBoundedJson(response, 64 * 1024, schema).pipe(Effect.mapError(() => new GitHubAppError({ stage: "exchange" })));
53
+ });
54
+ }
55
+ //# sourceMappingURL=githubApp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubApp.js","sourceRoot":"","sources":["../src/githubApp.ts"],"names":[],"mappings":"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"}
package/dist/json.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { Effect, Schema } from "effect";
2
+ import type { CachedResponse } from "./cache.ts";
3
+ export declare const decodeJson: <TSchema extends Schema.Constraint>(entry: CachedResponse, schema: TSchema) => Effect.Effect<TSchema["Type"], Schema.SchemaError, TSchema["DecodingServices"]>;
4
+ export declare function jsonResponse(entry: CachedResponse): {
5
+ decode: <TSchema extends Schema.Constraint>(schema: TSchema) => Effect.Effect<TSchema["Type"], Schema.SchemaError, TSchema["DecodingServices"]>;
6
+ };
7
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,UAAU,GAAgC,OAAO,SAAS,MAAM,CAAC,UAAU,4HAQtF,CAAC;AAEH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc;IACxC,MAAM,GAAG,OAAO,SAAS,MAAM,CAAC,UAAU,UAAU,OAAO;EACpE"}
package/dist/json.js ADDED
@@ -0,0 +1,14 @@
1
+ import { Effect, Schema } from "effect";
2
+ export const decodeJson = Effect.fnUntraced(function* (entry, schema) {
3
+ const cached = entry.decoded.get(schema);
4
+ if (entry.decoded.has(schema) && Schema.is(schema)(cached)) {
5
+ return cached;
6
+ }
7
+ const value = yield* Schema.decodeUnknownEffect(Schema.fromJsonString(schema))(new TextDecoder().decode(entry.bytes));
8
+ entry.decoded.set(schema, value);
9
+ return value;
10
+ });
11
+ export function jsonResponse(entry) {
12
+ return { decode: (schema) => decodeJson(entry, schema) };
13
+ }
14
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGxC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAqC,KAAqB,EAAE,MAAe;IAC/H,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5D,OAAO,MAAM,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACtH,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACjC,OAAO,KAAK,CAAC;AACd,CAAC,CAAC,CAAC;AAEH,MAAM,UAAU,YAAY,CAAC,KAAqB;IACjD,OAAO,EAAE,MAAM,EAAE,CAAoC,MAAe,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;AACtG,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function plainText(text: string): string;
2
+ export declare function codeSpan(text: string): string;
3
+ export declare function tableCell(text: string, format?: "text" | "code"): string;
4
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY7C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,MAAe,GAAG,MAAM,CAGhF"}
@@ -0,0 +1,24 @@
1
+ export function plainText(text) {
2
+ return text.replace(/[!-/:-@[-`{-~]/gu, (character) => {
3
+ const separator = character === "@" || character === "#" ? "&#8203;" : "";
4
+ return `&#${character.charCodeAt(0)};${separator}`;
5
+ });
6
+ }
7
+ export function codeSpan(text) {
8
+ const content = text.replace(/\r\n|\r|\n/gu, " ");
9
+ if (content === "") {
10
+ return "";
11
+ }
12
+ let longest = 0;
13
+ for (const [run] of content.matchAll(/`+/gu)) {
14
+ longest = Math.max(longest, run.length);
15
+ }
16
+ const fence = "`".repeat(longest + 1);
17
+ const pad = content.startsWith("`") || content.endsWith("`") || (/^ .* $/u.test(content) && /[^ ]/u.test(content)) ? " " : "";
18
+ return `${fence}${pad}${content}${pad}${fence}`;
19
+ }
20
+ export function tableCell(text, format = "text") {
21
+ const content = text.replace(/\r\n|[\r\n\u2028\u2029]/gu, " ");
22
+ return format === "code" ? codeSpan(content.replaceAll("|", "\\|")) : plainText(content);
23
+ }
24
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CAAC,IAAY;IACrC,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,SAAS,EAAE,EAAE;QACrD,MAAM,SAAS,GAAG,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,KAAK,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IAClD,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QACpB,OAAO,EAAE,CAAC;IACX,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9H,OAAO,GAAG,KAAK,GAAG,GAAG,GAAG,OAAO,GAAG,GAAG,GAAG,KAAK,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,MAAM,GAAoB,MAAM;IACvE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;IAC/D,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface MarkdownRowsOptions {
2
+ readonly byteLimit?: number;
3
+ readonly header?: string;
4
+ }
5
+ export declare function renderRows(rows: readonly string[], { byteLimit, header }?: MarkdownRowsOptions): string;
6
+ //# sourceMappingURL=markdownRows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownRows.d.ts","sourceRoot":"","sources":["../src/markdownRows.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,SAAkB,EAAE,MAAW,EAAE,GAAE,mBAAwB,GAAG,MAAM,CAwBzH"}
@@ -0,0 +1,26 @@
1
+ export function renderRows(rows, { byteLimit = 60_000, header = "" } = {}) {
2
+ const encoder = new TextEncoder();
3
+ const sizes = [0];
4
+ for (const row of rows) {
5
+ sizes.push((sizes.at(-1) ?? 0) + encoder.encode(row).byteLength + 1);
6
+ }
7
+ const headerBytes = encoder.encode(header).byteLength;
8
+ function bodySize(kept) {
9
+ return headerBytes + (kept > 0 ? (header === "" ? 0 : 1) + (sizes[kept] ?? 0) - 1 : 0);
10
+ }
11
+ function body(kept) {
12
+ return [...(header === "" ? [] : [header]), ...rows.slice(0, kept)].join("\n");
13
+ }
14
+ if (bodySize(rows.length) <= byteLimit) {
15
+ return body(rows.length);
16
+ }
17
+ for (let kept = rows.length - 1; kept >= 0; kept -= 1) {
18
+ const notice = `and ${rows.length - kept} more`;
19
+ const separator = kept > 0 || header !== "" ? "\n\n" : "";
20
+ if (bodySize(kept) + separator.length + encoder.encode(notice).byteLength <= byteLimit) {
21
+ return body(kept) + separator + notice;
22
+ }
23
+ }
24
+ throw new RangeError("The byte limit must fit the header and omitted-row notice");
25
+ }
26
+ //# sourceMappingURL=markdownRows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownRows.js","sourceRoot":"","sources":["../src/markdownRows.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,UAAU,CAAC,IAAuB,EAAE,EAAE,SAAS,GAAG,MAAM,EAAE,MAAM,GAAG,EAAE,EAAE,GAAwB,EAAE;IAChH,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAClB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC;IACtD,SAAS,QAAQ,CAAC,IAAY;QAC7B,OAAO,WAAW,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,CAAC;IACD,SAAS,IAAI,CAAC,IAAY;QACzB,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,OAAO,CAAC;QAChD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,IAAI,SAAS,EAAE,CAAC;YACxF,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC;QACxC,CAAC;IACF,CAAC;IACD,MAAM,IAAI,UAAU,CAAC,2DAA2D,CAAC,CAAC;AACnF,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { DateTime, Effect } from "effect";
2
+ import type { HttpClientResponse } from "effect/http";
3
+ import type { GitHubRateLimited } from "./errors.ts";
4
+ export interface RateLimitObservation {
5
+ readonly limit: number;
6
+ readonly remaining: number;
7
+ readonly reset: DateTime.Utc;
8
+ readonly resource: string;
9
+ readonly used: number;
10
+ }
11
+ export declare function rateLimits(): {
12
+ blocked: Map<string, GitHubRateLimited>;
13
+ failures: Map<string, number>;
14
+ observations: Map<string, RateLimitObservation>;
15
+ observe(response: HttpClientResponse.HttpClientResponse): string;
16
+ resource: (path: string) => string;
17
+ };
18
+ export type RateLimits = ReturnType<typeof rateLimits>;
19
+ export declare const failRateLimited: (path: string, error: GitHubRateLimited, remaining: number | undefined) => Effect.Effect<never, GitHubRateLimited, never>;
20
+ //# sourceMappingURL=rateLimits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimits.d.ts","sourceRoot":"","sources":["../src/rateLimits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,UAAU;;;;sBAYN,kBAAkB,CAAC,kBAAkB;qBAPhC,MAAM;EA0B9B;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAEvD,eAAO,MAAM,eAAe,2HAQ1B,CAAC"}