@effected/github 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ActionsOidc.js CHANGED
@@ -143,7 +143,8 @@ const testClaims = (overrides = {}) => ({
143
143
  * @remarks
144
144
  * {@link ActionsOidc.verify} is `@effected/oidc`'s `Oidc.verify` pinned to the
145
145
  * Actions issuer: it checks the signature against GitHub's published JWKS
146
- * (through `@effected/jwt`'s `JwksResolver`, which caches it), then `iss`,
146
+ * (through `@effected/jwt`'s `JwksResolver`, which caches it; the signature
147
+ * itself runs on core `effect/jose` and needs core's `Signature` service), then `iss`,
147
148
  * `aud`, `exp`, `nbf` and `iat`, then decodes the payload into
148
149
  * {@link ActionsOidcClaims}. Every failure is a `JwtError`; route on its
149
150
  * `reason` (`wrongAudience`, `expired`, `claims`, ...), never on its message.
@@ -168,7 +169,8 @@ const testClaims = (overrides = {}) => ({
168
169
  * ```ts
169
170
  * import { JwksResolver } from "@effected/jwt";
170
171
  * import { ActionsOidc } from "@effected/github";
171
- * import { Data, Effect } from "effect";
172
+ * import { Data, Effect, Layer } from "effect";
173
+ * import { SecureRandom, Signature } from "effect/crypto";
172
174
  *
173
175
  * class Forbidden extends Data.TaggedError("Forbidden")<{ readonly repositoryId: number }> {}
174
176
  *
@@ -186,7 +188,8 @@ const testClaims = (overrides = {}) => ({
186
188
  * });
187
189
  *
188
190
  * // JwksResolver.layer needs an HttpClient and a JwksStore, provided once at the edge.
189
- * export const program = authorize("eyJ...").pipe(Effect.provide(JwksResolver.layer));
191
+ * const CryptoLive = Signature.layerWebCrypto.pipe(Layer.provide(SecureRandom.layerWebCrypto));
192
+ * export const program = authorize("eyJ...").pipe(Effect.provide(Layer.merge(JwksResolver.layer, CryptoLive)));
190
193
  * ```
191
194
  *
192
195
  * @public
@@ -195,7 +198,7 @@ var ActionsOidc = class {
195
198
  constructor() {}
196
199
  /** The Actions OIDC issuer, `https://token.actions.githubusercontent.com`. */
197
200
  static issuer = ISSUER;
198
- /** Verify a runner-issued OIDC token: signature against GitHub's JWKS, iss, aud, exp/nbf, then typed claims. */
201
+ /** Verify a runner-issued OIDC token: signature against GitHub's JWKS, iss, aud, exp/nbf, then typed claims; requires `JwksResolver` and core `Signature`. */
199
202
  static verify = verify;
200
203
  /**
201
204
  * A valid claims payload for tests, overridable field by field.
package/GitHubApp.js CHANGED
@@ -7,6 +7,7 @@ import { numericId } from "./internal/ids.js";
7
7
  import { InstallationTokenStore } from "./InstallationTokenStore.js";
8
8
  import { Cause, Clock, Context, DateTime, Deferred, Duration, Effect, Layer, Option, Redacted, Ref, Schema, Semaphore, Stream } from "effect";
9
9
  import { Jwt, JwtKey } from "@effected/jwt";
10
+ import { Signature } from "effect/crypto";
10
11
 
11
12
  // src/GitHubApp.ts
12
13
  /**
@@ -355,7 +356,7 @@ var GitHubApp = class GitHubApp extends Context.Service()("@effected/github/GitH
355
356
  * Effect.runPromise(Effect.provide(sweep, layer));
356
357
  * ```
357
358
  */
358
- static appClientLayer = (credentials, options = {}) => Layer.effect(GitHubClient, makeRotatingClient(mintJwt(credentials), () => Effect.void, options, "GitHubApp.appClientLayer"));
359
+ static appClientLayer = (credentials, options = {}) => Layer.effect(GitHubClient, Effect.flatMap(Effect.service(Signature.Signature), (signature) => makeRotatingClient(Effect.provideService(mintJwt(credentials), Signature.Signature, signature), () => Effect.void, options, "GitHubApp.appClientLayer")));
359
360
  /**
360
361
  * An installation token, reused from an {@link InstallationTokenStore}
361
362
  * while it has `margin` (five minutes by default) left to live.
@@ -534,7 +535,7 @@ const mintJwt = (credentials) => Effect.gen(function* () {
534
535
  };
535
536
  }).pipe(Effect.catchTag("JwtError", (error) => Effect.fail(GitHubAppError.of("jwt", error.detail, error))));
536
537
  /** A client speaking as the app itself. */
537
- const asApp = (credentials, options) => Effect.flatMap(mintJwt(credentials), ({ token }) => makeClientShape({
538
+ const appClientOf = (credentials, options) => Effect.flatMap(mintJwt(credentials), ({ token }) => makeClientShape({
538
539
  ...options,
539
540
  token
540
541
  }));
@@ -545,75 +546,77 @@ const asBearer = (token, options) => makeClientShape({
545
546
  });
546
547
  const appFailure = (kind) => (error) => Effect.fail(GitHubAppError.of(kind, error.reason, error));
547
548
  function makeApp(options) {
548
- return Effect.map(resolveApiVersion(options.apiVersion), () => {
549
- const installations = Effect.fn("GitHubApp.installations")(function* (credentials) {
550
- return (yield* (yield* asApp(credentials, options)).paginate("GET /app/installations", {}).pipe(Effect.catch(appFailure("installation")))).map((entry) => {
551
- const account = entry.account ?? void 0;
552
- return Installation.make({
553
- id: numericId(entry.id),
554
- ...account !== void 0 && typeof account.login === "string" ? { account: account.login } : {},
555
- ...readField("accountType", Schema.String, account?.type),
556
- ...readField("accountId", Schema.Int, typeof account?.id === "bigint" ? numericId(account.id) : account?.id),
557
- ...readField("suspendedAt", SuspendedAt, entry.suspended_at),
558
- ...readField("updatedAt", Schema.DateTimeUtcFromString, entry.updated_at)
559
- });
549
+ return Effect.flatMap(Effect.service(Signature.Signature), (signature) => Effect.map(resolveApiVersion(options.apiVersion), () => makeAppWith(options, signature)));
550
+ }
551
+ function makeAppWith(options, signature) {
552
+ const asApp = (credentials, clientOptions) => Effect.provideService(appClientOf(credentials, clientOptions), Signature.Signature, signature);
553
+ const installations = Effect.fn("GitHubApp.installations")(function* (credentials) {
554
+ return (yield* (yield* asApp(credentials, options)).paginate("GET /app/installations", {}).pipe(Effect.catch(appFailure("installation")))).map((entry) => {
555
+ const account = entry.account ?? void 0;
556
+ return Installation.make({
557
+ id: numericId(entry.id),
558
+ ...account !== void 0 && typeof account.login === "string" ? { account: account.login } : {},
559
+ ...readField("accountType", Schema.String, account?.type),
560
+ ...readField("accountId", Schema.Int, typeof account?.id === "bigint" ? numericId(account.id) : account?.id),
561
+ ...readField("suspendedAt", SuspendedAt, entry.suspended_at),
562
+ ...readField("updatedAt", Schema.DateTimeUtcFromString, entry.updated_at)
560
563
  });
561
564
  });
562
- const resolveInstallationId = (request) => request.installationId !== void 0 ? Effect.succeed(request.installationId) : Effect.gen(function* () {
563
- const all = yield* installations(request);
564
- if (request.owner !== void 0) {
565
- const wanted = request.owner.toLowerCase();
566
- const match = all.find((entry) => entry.account?.toLowerCase() === wanted);
567
- if (match !== void 0) return match.id;
568
- return yield* Effect.fail(GitHubAppError.of("installation", `the app is not installed on ${request.owner} (installed on: ${all.map((entry) => entry.account ?? entry.id).join(", ") || "nothing"})`));
569
- }
570
- const only = all[0];
571
- if (all.length === 1 && only !== void 0) return only.id;
572
- return yield* Effect.fail(GitHubAppError.of("installation", all.length === 0 ? "the app has no installations" : `the app has ${all.length} installations; pass installationId or owner`));
573
- });
574
- const token = Effect.fn("GitHubApp.token")(function* (request) {
575
- const installationId = yield* resolveInstallationId(request);
576
- const minted = yield* (yield* asApp(request, options)).request("POST /app/installations/{installation_id}/access_tokens", { installation_id: installationId }).pipe(Effect.catch(appFailure("token")));
577
- return yield* Schema.decodeUnknownEffect(InstallationToken)({
578
- token: minted.token,
579
- expiresAt: minted.expires_at,
580
- installationId,
581
- permissions: normalizePermissions(minted.permissions)
582
- }).pipe(Effect.catchTag("SchemaError", (error) => Effect.fail(GitHubAppError.of("token", "GitHub returned an unexpected token payload", error))));
583
- });
584
- const revoke = Effect.fn("GitHubApp.revoke")(function* (value) {
585
- yield* (yield* asBearer(value, options)).request("DELETE /installation/token", {}).pipe(Effect.catch(appFailure("revoke")));
586
- });
587
- const scopedToken = (request) => Effect.acquireRelease(token(request), (minted) => Effect.ignore(revoke(minted.token)));
588
- return {
589
- token,
590
- scopedToken,
591
- revoke,
592
- identity: Effect.fn("GitHubApp.identity")(function* (request) {
593
- const app = yield* (yield* asApp(request, options)).request("GET /app", {}).pipe(Effect.catch(appFailure("identity")));
594
- if (app === null) return yield* Effect.fail(GitHubAppError.of("identity", "GET /app returned no app"));
595
- const slug = app.slug ?? "";
596
- const name = app.name;
597
- const user = yield* (yield* asBearer(request.installationToken, options)).request("GET /users/{username}", { username: `${slug}[bot]` }).pipe(Effect.option);
598
- return AppIdentity.make({
599
- slug,
600
- name,
601
- ...Option.isSome(user) ? { userId: numericId(user.value.id) } : {}
602
- });
603
- }),
604
- botUser: Effect.fn("GitHubApp.botUser")(function* (request) {
605
- yield* Effect.annotateCurrentSpan({ slug: request.slug });
606
- const user = yield* (yield* asBearer(request.installationToken, options)).request("GET /users/{username}", { username: `${request.slug}[bot]` }).pipe(Effect.catch(appFailure("identity")));
607
- const raw = user;
608
- return yield* Schema.decodeUnknownEffect(BotUser)(typeof raw === "object" && raw !== null ? {
609
- id: numericId(user.id),
610
- login: user.login
611
- } : raw).pipe(Effect.catchTag("SchemaError", (error) => Effect.fail(GitHubAppError.of("identity", "GitHub returned an unexpected bot user", error))));
612
- }),
613
- installations,
614
- cachedToken: makeCachedToken(token)
615
- };
616
565
  });
566
+ const resolveInstallationId = (request) => request.installationId !== void 0 ? Effect.succeed(request.installationId) : Effect.gen(function* () {
567
+ const all = yield* installations(request);
568
+ if (request.owner !== void 0) {
569
+ const wanted = request.owner.toLowerCase();
570
+ const match = all.find((entry) => entry.account?.toLowerCase() === wanted);
571
+ if (match !== void 0) return match.id;
572
+ return yield* Effect.fail(GitHubAppError.of("installation", `the app is not installed on ${request.owner} (installed on: ${all.map((entry) => entry.account ?? entry.id).join(", ") || "nothing"})`));
573
+ }
574
+ const only = all[0];
575
+ if (all.length === 1 && only !== void 0) return only.id;
576
+ return yield* Effect.fail(GitHubAppError.of("installation", all.length === 0 ? "the app has no installations" : `the app has ${all.length} installations; pass installationId or owner`));
577
+ });
578
+ const token = Effect.fn("GitHubApp.token")(function* (request) {
579
+ const installationId = yield* resolveInstallationId(request);
580
+ const minted = yield* (yield* asApp(request, options)).request("POST /app/installations/{installation_id}/access_tokens", { installation_id: installationId }).pipe(Effect.catch(appFailure("token")));
581
+ return yield* Schema.decodeUnknownEffect(InstallationToken)({
582
+ token: minted.token,
583
+ expiresAt: minted.expires_at,
584
+ installationId,
585
+ permissions: normalizePermissions(minted.permissions)
586
+ }).pipe(Effect.catchTag("SchemaError", (error) => Effect.fail(GitHubAppError.of("token", "GitHub returned an unexpected token payload", error))));
587
+ });
588
+ const revoke = Effect.fn("GitHubApp.revoke")(function* (value) {
589
+ yield* (yield* asBearer(value, options)).request("DELETE /installation/token", {}).pipe(Effect.catch(appFailure("revoke")));
590
+ });
591
+ const scopedToken = (request) => Effect.acquireRelease(token(request), (minted) => Effect.ignore(revoke(minted.token)));
592
+ return {
593
+ token,
594
+ scopedToken,
595
+ revoke,
596
+ identity: Effect.fn("GitHubApp.identity")(function* (request) {
597
+ const app = yield* (yield* asApp(request, options)).request("GET /app", {}).pipe(Effect.catch(appFailure("identity")));
598
+ if (app === null) return yield* Effect.fail(GitHubAppError.of("identity", "GET /app returned no app"));
599
+ const slug = app.slug ?? "";
600
+ const name = app.name;
601
+ const user = yield* (yield* asBearer(request.installationToken, options)).request("GET /users/{username}", { username: `${slug}[bot]` }).pipe(Effect.option);
602
+ return AppIdentity.make({
603
+ slug,
604
+ name,
605
+ ...Option.isSome(user) ? { userId: numericId(user.value.id) } : {}
606
+ });
607
+ }),
608
+ botUser: Effect.fn("GitHubApp.botUser")(function* (request) {
609
+ yield* Effect.annotateCurrentSpan({ slug: request.slug });
610
+ const user = yield* (yield* asBearer(request.installationToken, options)).request("GET /users/{username}", { username: `${request.slug}[bot]` }).pipe(Effect.catch(appFailure("identity")));
611
+ const raw = user;
612
+ return yield* Schema.decodeUnknownEffect(BotUser)(typeof raw === "object" && raw !== null ? {
613
+ id: numericId(user.id),
614
+ login: user.login
615
+ } : raw).pipe(Effect.catchTag("SchemaError", (error) => Effect.fail(GitHubAppError.of("identity", "GitHub returned an unexpected bot user", error))));
616
+ }),
617
+ installations,
618
+ cachedToken: makeCachedToken(token)
619
+ };
617
620
  }
618
621
  /** GitHub's permission values are strings; anything else is not a permission. */
619
622
  const normalizePermissions = (raw) => {
package/README.md CHANGED
@@ -8,10 +8,10 @@
8
8
  Typed GitHub REST and GraphQL for [Effect](https://effect.website) v4. `client.request("GET /repos/{owner}/{repo}", { owner, repo })` types both the parameters and the returned `data` from the route literal alone — no `operation: string`, no callback, no cast. One `GitHubError` covers every REST failure with a `kind` you branch on instead of grepping a message, one pagination engine backs every paginating route and `client.request`'s `Stream` form, and a set of resource services (`GitBranch`, `GitTag`, `CheckRun`, `PullRequest`, `PullRequestComment`, `GitHubRelease`, `Attestation`) turn multi-call dances — "does this branch already exist?", "conclude this check run no matter how the program exits" — into one call. A second tier writes the configuration half: secrets, variables, rulesets, deployment environments, the security toggles and CodeQL default setup. `GitHubApp` mints and revokes installation tokens for App auth.
9
9
 
10
10
  > **Pre-`1.0.0`.** This package is part of the `@effected/*` kit, built on stable
11
- > Effect v4 (`effect` `^4.0.0`) and still in `0.x` development. Stable Effect
11
+ > Effect v4 (`effect` `~4.1.0`) and still in `0.x` development. Stable Effect
12
12
  > makes a kit `1.0.0` possible, not automatic. To keep your `effect` and
13
13
  > `@effect/*` versions on the line the kit is built and tested against, install
14
- > [`@effected/pnpm-plugin-effect`](https://www.npmjs.com/package/@effected/pnpm-plugin-effect).
14
+ > [`@effected/pnpm-plugin-effected`](https://www.npmjs.com/package/@effected/pnpm-plugin-effected).
15
15
  >
16
16
  > **Stability: unstable.** This package's API surface is not yet considered
17
17
  > complete and may change across `0.x` releases. Pin an exact version — even a
@@ -25,7 +25,7 @@ Hand-rolled octokit wrappers tend to converge on the same shape: a `rest<T>(oper
25
25
 
26
26
  The error model gets the same treatment. `GitHubError.kind` is a literal union (`notFound`, `alreadyExists`, `rejected`, `unauthorized`, `rateLimited`, `transport`, `decode`) produced by one classification step, `GitHubError.fromOctokit`, instead of one hand-written mapper per resource. `kind: "alreadyExists"` is what makes `GitBranch.upsert` and `GitTag.upsert` a single round trip in the common case, rather than a create-then-catch-then-check-then-reset dance repeated at every call site that needs it.
27
27
 
28
- This package also owns the octokit runtime so nothing downstream has to. `@octokit/rest` and `@octokit/auth-app` are deliberately absent — the rest wrapper is a request-logging plugin plus 1.4 MB of duplicate endpoint types, and `auth-app` drags in `createOAuthUserAuth`, roughly 492 KB of OAuth machinery this package never calls. GitHub App JWTs are signed by the kit's own `@effected/jwt` instead: WebCrypto RS256 with no runtime dependencies, so App auth runs on Cloudflare Workers as well as Node. A consumer that only authenticates with a token it already holds never links the JWT signer at all: the App-authenticated layer lives in its own module (`GitHubApp`), and nothing here is gathered into a namespace object that would defeat that split.
28
+ This package also owns the octokit runtime so nothing downstream has to. `@octokit/rest` and `@octokit/auth-app` are deliberately absent — the rest wrapper is a request-logging plugin plus 1.4 MB of duplicate endpoint types, and `auth-app` drags in `createOAuthUserAuth`, roughly 492 KB of OAuth machinery this package never calls. GitHub App JWTs are signed by the kit's own `@effected/jwt` instead, over core `effect/jose`: RS256 with no extra runtime dependencies, so App auth runs on Cloudflare Workers as well as Node. The App layers (`GitHubApp.layer`, `layerWith`, `clientLayer`, `appClientLayer`) require core's `Signature` service; provide `Signature.layerWebCrypto.pipe(Layer.provide(SecureRandom.layerWebCrypto))` from `effect/crypto` once at the edge. A consumer that only authenticates with a token it already holds never links the JWT signer at all: the App-authenticated layer lives in its own module (`GitHubApp`), and nothing here is gathered into a namespace object that would defeat that split.
29
29
 
30
30
  ## Install
31
31
 
package/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { BareLineReference, CLOSING_KEYWORDS, ClosingKeyword, IssueReference, harvestIssueReferences, parseBareLineReference } from "@effected/github-references";
2
2
  import { JwksResolver, JwtError } from "@effected/jwt";
3
3
  import { Cause, Config, Context, Duration, Effect, Layer, Option, Redacted, Result, Schedule, Schema, Scope, Stream } from "effect";
4
+ import { Signature } from "effect/crypto";
4
5
  import { PaginatingEndpoints } from "@octokit/plugin-paginate-rest";
5
6
  import { Endpoints, RequestHeaders } from "@octokit/types";
6
7
  import { SemVer } from "@effected/semver";
@@ -126,7 +127,8 @@ interface ActionsOidcVerifyOptions {
126
127
  * @remarks
127
128
  * {@link ActionsOidc.verify} is `@effected/oidc`'s `Oidc.verify` pinned to the
128
129
  * Actions issuer: it checks the signature against GitHub's published JWKS
129
- * (through `@effected/jwt`'s `JwksResolver`, which caches it), then `iss`,
130
+ * (through `@effected/jwt`'s `JwksResolver`, which caches it; the signature
131
+ * itself runs on core `effect/jose` and needs core's `Signature` service), then `iss`,
130
132
  * `aud`, `exp`, `nbf` and `iat`, then decodes the payload into
131
133
  * {@link ActionsOidcClaims}. Every failure is a `JwtError`; route on its
132
134
  * `reason` (`wrongAudience`, `expired`, `claims`, ...), never on its message.
@@ -151,7 +153,8 @@ interface ActionsOidcVerifyOptions {
151
153
  * ```ts
152
154
  * import { JwksResolver } from "@effected/jwt";
153
155
  * import { ActionsOidc } from "@effected/github";
154
- * import { Data, Effect } from "effect";
156
+ * import { Data, Effect, Layer } from "effect";
157
+ * import { SecureRandom, Signature } from "effect/crypto";
155
158
  *
156
159
  * class Forbidden extends Data.TaggedError("Forbidden")<{ readonly repositoryId: number }> {}
157
160
  *
@@ -169,7 +172,8 @@ interface ActionsOidcVerifyOptions {
169
172
  * });
170
173
  *
171
174
  * // JwksResolver.layer needs an HttpClient and a JwksStore, provided once at the edge.
172
- * export const program = authorize("eyJ...").pipe(Effect.provide(JwksResolver.layer));
175
+ * const CryptoLive = Signature.layerWebCrypto.pipe(Layer.provide(SecureRandom.layerWebCrypto));
176
+ * export const program = authorize("eyJ...").pipe(Effect.provide(Layer.merge(JwksResolver.layer, CryptoLive)));
173
177
  * ```
174
178
  *
175
179
  * @public
@@ -178,8 +182,8 @@ export declare class ActionsOidc {
178
182
  private constructor();
179
183
  /** The Actions OIDC issuer, `https://token.actions.githubusercontent.com`. */
180
184
  static readonly issuer: "https://token.actions.githubusercontent.com";
181
- /** Verify a runner-issued OIDC token: signature against GitHub's JWKS, iss, aud, exp/nbf, then typed claims. */
182
- static readonly verify: (token: string, options: ActionsOidcVerifyOptions) => Effect.Effect<ActionsOidcClaims, JwtError, JwksResolver>;
185
+ /** Verify a runner-issued OIDC token: signature against GitHub's JWKS, iss, aud, exp/nbf, then typed claims; requires `JwksResolver` and core `Signature`. */
186
+ static readonly verify: (token: string, options: ActionsOidcVerifyOptions) => Effect.Effect<ActionsOidcClaims, JwtError, JwksResolver | Signature.Signature>;
183
187
  /**
184
188
  * A valid claims payload for tests, overridable field by field.
185
189
  *
@@ -2848,7 +2852,7 @@ declare const GitHubApp_base: Context.ServiceClass<GitHubApp, "@effected/github/
2848
2852
  */
2849
2853
  export declare class GitHubApp extends GitHubApp_base {
2850
2854
  /** The default transport. Bind it once; layers are memoized by reference. */
2851
- static readonly layer: Layer.Layer<GitHubApp>;
2855
+ static readonly layer: Layer.Layer<GitHubApp, never, Signature.Signature>;
2852
2856
  /**
2853
2857
  * A transport with custom settings.
2854
2858
  *
@@ -2857,7 +2861,7 @@ export declare class GitHubApp extends GitHubApp_base {
2857
2861
  * this at two provide sites builds two instances, because layers are
2858
2862
  * memoized by reference.
2859
2863
  */
2860
- static readonly layerWith: (options: GitHubAppOptions) => Layer.Layer<GitHubApp>;
2864
+ static readonly layerWith: (options: GitHubAppOptions) => Layer.Layer<GitHubApp, never, Signature.Signature>;
2861
2865
  /**
2862
2866
  * A {@link GitHubClient} authenticated as an app installation.
2863
2867
  *
@@ -2876,7 +2880,7 @@ export declare class GitHubApp extends GitHubApp_base {
2876
2880
  * authorization failure, and widening every method's error channel to say so
2877
2881
  * would tax every caller for a case only this layer can produce.
2878
2882
  */
2879
- static readonly clientLayer: (request: TokenRequest, options?: GitHubAppOptions) => Layer.Layer<GitHubClient, GitHubAppError>;
2883
+ static readonly clientLayer: (request: TokenRequest, options?: GitHubAppOptions) => Layer.Layer<GitHubClient, GitHubAppError, Signature.Signature>;
2880
2884
  /**
2881
2885
  * A {@link GitHubClient} authenticated as the app itself, with an App JWT.
2882
2886
  *
@@ -2929,7 +2933,7 @@ export declare class GitHubApp extends GitHubApp_base {
2929
2933
  * Effect.runPromise(Effect.provide(sweep, layer));
2930
2934
  * ```
2931
2935
  */
2932
- static readonly appClientLayer: (credentials: AppCredentials, options?: GitHubAppOptions) => Layer.Layer<GitHubClient, GitHubAppError>;
2936
+ static readonly appClientLayer: (credentials: AppCredentials, options?: GitHubAppOptions) => Layer.Layer<GitHubClient, GitHubAppError, Signature.Signature>;
2933
2937
  /**
2934
2938
  * An installation token, reused from an {@link InstallationTokenStore}
2935
2939
  * while it has `margin` (five minutes by default) left to live.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/github",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "private": false,
5
5
  "description": "Typed GitHub REST and GraphQL services over the octokit core request surface, with app auth and resource helpers.",
6
6
  "keywords": [
@@ -38,11 +38,11 @@
38
38
  "./package.json": "./package.json"
39
39
  },
40
40
  "dependencies": {
41
- "@effected/crypto": "^0.3.0",
42
- "@effected/github-references": "^0.12.0",
43
- "@effected/jwt": "^0.7.0",
44
- "@effected/oidc": "^0.2.0",
45
- "@effected/semver": "^0.19.0",
41
+ "@effected/crypto": "^0.4.0",
42
+ "@effected/github-references": "^0.13.0",
43
+ "@effected/jwt": "^0.8.0",
44
+ "@effected/oidc": "^0.3.0",
45
+ "@effected/semver": "^0.20.0",
46
46
  "@octokit/core": "^7.0.6",
47
47
  "@octokit/plugin-paginate-rest": "^16.0.0",
48
48
  "@octokit/types": "^18.0.0",
@@ -50,7 +50,7 @@
50
50
  "tweetnacl": "1.0.3"
51
51
  },
52
52
  "peerDependencies": {
53
- "effect": "^4.0.0"
53
+ "effect": "~4.1.0"
54
54
  },
55
55
  "engines": {
56
56
  "node": ">=24.11.0"
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.59.4"
8
+ "packageVersion": "7.60.0"
9
9
  }
10
10
  ]
11
11
  }