@effected/github

中文文档
0.32.1发布于 2026/11/11MITTypeScriptES Module构建来源已验证近 30 天下载 1.6万

在octokit核心请求表面上键入了 GitHub REST 和 GraphQL 服务, 并配备了应用认证和资源帮助器 .

中文使用文档
文档目录12 节
  1. 为什么
  2. 安装
  3. 快开始
  4. 资源服务
  5. 问题和最后参考资料
  6. 仓库配置
  7. GitHub 应用程序认证
  8. 充当用户: OAuth 网络流量
  9. 错误
  10. 测试
  11. 特征
  12. 许可证

@ effect/ github

npm License: MIT Node.js %3E%3D24.11.0 TypeScript 7.0

输入了 GitHub 的 REST 和 GraphQL 效果 v4 (英语). client.request("GET /repos/{owner}/{repo}", { owner, repo }) 键入参数并返回 data 单从路线字面上——没有 operation: string没有召回,没有铸币。 一个 GitHubError 以一个 kind 您可以切换到一条消息 而不是给它添加信息, 一个pagination 引擎可以回溯到每一个开始的路由 client.request是因为 Stream 格式,以及一组资源服务GitBranch, (中文(简体) ), GitTag, (中文(简体) ), CheckRun, (中文(简体) ), PullRequest, (中文(简体) ), PullRequestComment, (中文(简体) ), GitHubRelease, (中文(简体) ), Attestation)将多呼起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起起 第二层写出配置的一半:秘密,变量,规则,部署环境,安全切换和代码QL默认设置. GitHubApp 薄荷并取消 App auth 的安装令牌.

预1.0.0。 。 。 . 此软件包是 @effected/* 在稳定基础上建造的工具包 效应v4(effect ~4.1.0) 并仍在 0.x 发展。 稳定效果 制作一个工具箱 1.0.0 可能,不是自动的。 为了保持你的 effect 财务报告和审定财务报表 @effect/* 该工具包在线上构建和测试、安装 @effected/pnpm-plugin-effected。 。 。 .

稳定:不稳定. 此软件包的 API 表面尚未考虑 完成并可能改变 0.x 释放 定一个确切的版本——甚至 标记软件包 稳定 在此之前 1.0.0 可以引入突破性更改 和精确的针 变成一个类型检查错误 而不是一个 跑步时间惊喜。 完全政策: 释放策略。 。 。 .

为什么

手卷的octokit包装器往往在同一种形状上相会:a rest<T>(operation: string, fn: (octokit) => Promise<{ data: T }>) 帮助在哪里 T 不管打电话者写了什么 都与终点无关 此软件包的路由按键 request 缩小这一差距—— @octokit/types 已经从 GitHub 自己的 OpenAPI 描述生成了地图,并且 @octokit/core是因为 request 已经消耗了 所以也没有理由再造.

错误模型得到同样的处理. GitHubError.kind 字面结合( r) :notFound, (中文(简体) ), alreadyExists, (中文(简体) ), rejected, (中文(简体) ), unauthorized, (中文(简体) ), rateLimited, (中文(简体) ), transport, (中文(简体) ), decode)通过一个分类步骤产生, GitHubError.fromOctokit,而不是每个资源一个手写地图. kind: "alreadyExists" 是什么让 GitBranch.upsert 财务报告和审定财务报表 GitTag.upsert 而不是在每个需要的呼叫站点重复一次.

这个包还拥有Octokit运行时间,所以下游没有什么需要. @octokit/rest 财务报告和审定财务报表 @octokit/auth-app 故意缺席——其余的包装器是一个请求-博客插件外加1.4 MB的重复端点类型,以及 auth-app 拖入 createOAuthUserAuth大约492 KB的OAuth机器 这个包裹从来没有调用。 GitHub App JWT 由工具包自己签名 @effected/jwt 相反,在核心 effect/jose:RS256没有额外的运行时间依赖,因此App auth运行于Cloudflare Workers和Node上. App 层(GitHubApp.layer, (中文(简体) ), layerWith, (中文(简体) ), clientLayer, (中文(简体) ), appClientLayer) 需要核心的 Signature 服务; 提供 Signature.layerWebCrypto.pipe(Layer.provide(SecureRandom.layerWebCrypto)) 从 effect/crypto 一次在边缘。 一个只用它已经持有的标志进行认证的消费者,从不将JWT的标志连接起来: App - 认证层生活在自己的模块中(App - 认证层)GitHubApp)),这里没有任何物被集合到一个能够击败分裂的命名空间物体.

安装

npm install @effected/github effect
pnpm add @effected/github effect

需要节点.js~~24.11.0. effect v4 是一个对等依赖.

全体 @effected/* 软件包仅为无害环境管理:只公布出口地图 import 条件,所以 require() 包括解析 CJS 模式的工具 —— 与节点失败 ERR_PACKAGE_PATH_NOT_EXPORTED 而不是装入不存在的 CJS 建筑。 从ES模块导入.

快开始

import { GitHubClient, Repo, RepoRef } from "@effected/github";
import { Effect } from "effect";

const program = Effect.gen(function* () {
  const client = yield* GitHubClient;
  const repo = yield* client.request("GET /repos/{owner}/{repo}", { owner: "effect-ts", repo: "effect" });
  return repo.default_branch; // string — typed from the route literal, no cast
});

const ClientLayer = GitHubClient.layerFromConfig(); // reads GITHUB_TOKEN through the ambient ConfigProvider
const RepoLayer = Repo.layer(RepoRef.make({ owner: "effect-ts", repo: "effect" }));

Effect.runPromise(program.pipe(Effect.provide(ClientLayer), Effect.provide(RepoLayer))).then(console.log);
// the repository's default branch name, e.g. "main"

Repo 携带 { owner, repo } 坐标 R 而不是每个调用参数,所以下面的每一种资源方法都读作单一的表达. 在一个以上的寄存器上操作的程序 Repo.provide(otherRef) 围绕需要它的部分.

资源服务

每个资源都是服务结束 GitHubClient,拥有自己的 layer, (中文(简体) ), makeTest 财务报告和审定财务报表 layerTest。 。 。 . GitBranch.upsert 促使整个集:

import { GitBranch, GitHubClient, Repo } from "@effected/github";
import { Effect } from "effect";

const program = Effect.gen(function* () {
  const branches = yield* GitBranch;
  return yield* branches.upsert("release/1.2", "abc123");
});
// Effect<"created" | "reset", GitHubError, GitBranch | Repo>
// one round trip in the common case, two in the raced one — never four

CheckRun.withCheckRun 在检查运行中运行一个程序,并在每一个退出路径上完成它——成功,输入失败,缺陷或中断——所以运行永远不会被卡住 in_progress数字 :

import { CheckRun } from "@effected/github";
import { Effect } from "effect";

declare const lint: () => Effect.Effect<ReadonlyArray<string>>;
declare const deriveConclusion: (findings: ReadonlyArray<string>) => "success" | "neutral" | "failure";

const program = Effect.gen(function* () {
  const check = yield* CheckRun;
  return yield* check.withCheckRun("lint", "abc123", (_id, conclude) =>
    Effect.gen(function* () {
      const findings = yield* lint();
      yield* conclude(deriveConclusion(findings));
      return findings;
    }),
  );
});

GitTag.latestSemver 步行标记,并选择最新版本的一 在单一的通过,结束 @effected/semver同步比较者——每个候选人不得来回. PullRequest.upsert 财务报告和审定财务报表 PullRequestComment.upsert (一个标记-标记粘贴的注释)跟随同一个一呼一指的形状.

问题和最后参考资料

GitHubIssue 包括问题:读取、列表、创建、关闭、评论以及解答拉动请求的GraphQL侧. commentOnce 是创建或斯基普对应的 PullRequestComment.upsert ——它贴出一个有标记的评论,从来不编辑一个,这是你想要的公告,如果在事实发生后有所改变,它会读作历史的改写:

import { CommentMarker, GitHubIssue } from "@effected/github";
import { Effect } from "effect";

const marker = CommentMarker.make({ namespace: "release-bot", key: "shipped" });

const program = Effect.gen(function* () {
  const issues = yield* GitHubIssue;
  return yield* issues.commentOnce(1873, marker, "Shipped in the release just published.");
});
// CommentOnceResult — `wrote: true` when this call posted the comment,
// `wrote: false` when the marker was already there and nothing was sent.
// `comment` is the marked comment either way.

存在检查将问题的评论页到末尾并匹配标记 upsert准确的拼写,所以任何一位成员写出的评论都能够被另一位成员找到. 它是一个外观前写:在同一个问题上的两次跑跑都可以看到没有标记和两个帖子,所以把标记当作记录而不是把支票当作锁.

跑步是否应该评论,通常会转而发布拉出请求的结束,而这是一个语法而不是API调用. 这个语法现在住在 @effected/github-references,一个没有octokit的纯软件包后面;这个软件包再导出它曾经拥有的两种方言,这样现有的代码不断编译:

import { harvestIssueReferences, parseBareLineReference } from "@effected/github";

console.log(harvestIssueReferences("Fixes #12 and closes #13."));
// [ { issueNumber: 12, keyword: "fixes", start: 0, end: 9 },
//   { issueNumber: 13, keyword: "closes", start: 14, end: 24 } ]

console.log(parseBareLineReference("Closes: #12"));
// Option.some({ issueNumber: 12, keyword: "closes" })

console.log(parseBareLineReference("closes #12 for real"));
// Option.none() — the bare-line dialect takes the whole line or nothing

harvestIssueReferences 读取 内在辩护 方言:9个收尾关键词之一(CLOSING_KEYWORDS随后是白空间和 #<number>,在文本的任何地方,没有结肠——拼写"GitHub"本身扫描了拉取请求正文. 复制件按书面形式出现,因为 fixes #1, fixes #1 意思是一两个意图是打电话者的问题. parseBareLineReference 读取 光线 方言,其中整条被修剪的行为参考,而结肠是可选的——所生成的参考块写出形状,每行一出. 交叉重排( R)owner/repo#12)和全URL引用范围已超出范围.

再出口包括六个名字—— CLOSING_KEYWORDS, (中文(简体) ), ClosingKeyword, (中文(简体) ), IssueReference, (中文(简体) ), harvestIssueReferences, (中文(简体) ), BareLineReference, (中文(简体) ), parseBareLineReference 可在稍后释放时放弃。 从 @effected/github-references 直接用于新代码;它还包含第三个方言 这个包不再出口,关闭列表(Closes #247, #248 and #251) (中文(简体) ).

仓库配置

6项服务涵盖政策而不是内容库的一半: RepositorySecret, (中文(简体) ), RepositoryVariable, (中文(简体) ), Ruleset, (中文(简体) ), DeploymentEnvironment, (中文(简体) ), RepositorySecurity 财务报告和审定财务报表 CodeScanning。它们被设定为一个在整个舰队中应用相同配置的程序,因此每个列表都会读取页尾并截取一页不会成为错误的决定.

GitHub 的 API 要求的 libsodium 封存框中包含的秘密, 这就是为什么这个值是一个 Redacted<string> 而不是平庸的:

import { RepositorySecret } from "@effected/github";
import { Effect, Redacted } from "effect";

declare const token: string;

const program = Effect.gen(function* () {
  const secrets = yield* RepositorySecret;
  yield* secrets.set("NPM_TOKEN", Redacted.make(token)); // the "actions" store by default
  yield* secrets.setForEnvironment("production", "DEPLOY_KEY", Redacted.make(token));
  return yield* secrets.list("dependabot");
});
// ReadonlyArray<SecretInfo> — names only. GitHub returns a secret's value from no endpoint,
// so a diff against desired state detects a deleted secret and never an edited one.

actions, (中文(简体) ), dependabot 财务报告和审定财务报表 codespaces 在同一仓库的三个商店,每个商店都有自己的公用钥匙 scope 争论在他们之间挑出。 加密只存在于一个模块 RepositorySecret 所以一个从未写过秘密的消费者 就不会把密码对连起来. RepositoryVariable 对非秘密的值,镜像相同的六种方法 set 列表中的第一个原因是 GitHub 将创建并更新两个路径.

Ruleset.upsert 按名称匹配已有规则 财务报告和审定财务报表 source_type。第二个字段是投影带的原因: GET /repos/{owner}/{repo}/rulesets 返回一个寄存器与自己的组织一起继承的规则,仅根据名称进行匹配就可以让寄存器扫描写入 PUT 该组织的规则id——为该组织拥有的每一个存放处改写政策. Ruleset.teamId 财务报告和审定财务报表 Ruleset.roleId 解决一个绕行角色需要的数字标识,范围为组织 Repo。 。 。 .

其余随其端口自取粮. DeploymentEnvironment.upsert 是一个平地 PUT 因为GitHub的路线是一能的, 以及它的 delete 带着环境的秘密和变数, 确定任何清理通道的顺序. RepositorySecurity 读取和写取三个切换 GitHub 关闭了存储器的端点: 弱点警报、自动安全修正和私人脆弱性报告. CodeScanning.configure 应用一个 CodeQL 默认设置, 并在 GitHub 接受后立即返回 202 并同步配置,这里没有民意测验 CodeScanning.languages 报告 GitHub 在寄存器中检测到的, 即您在调用前过滤已配置语言列表 configure。 。 。 .

GitHubRepository 拥有仓库自己的设置. updateSettings 是忠实的键入 PATCH· ; applySettings 是上面的应用器, 取一张公开的地图, 将每个密钥导向 API 可以实际设置它

import { GitHubRepository } from "@effected/github";
import { Effect } from "effect";

const program = Effect.gen(function* () {
  const repository = yield* GitHubRepository;
  return yield* repository.applySettings({
    has_issues: true,
    has_sponsorships: false, // GraphQL-only: costs one extra read for the node id
    security_and_analysis: { secret_scanning: "enabled" },
  });
});
// AppliedSettings — { rest: [...], graphql: [...], ignored: [...] }, in the caller's own key names.
// The lists agree with the input right up until preparation drops a field
// GitHub would reject, which is what a person reading a dry run is checking for.
// `ignored` names keys neither API accepts (a typo, say): they are never sent,
// because the REST PATCH would ignore them and still answer 200. The REST key
// list is generated from GitHub's OpenAPI description; a key a later
// api-version removed is ignored only for a client pinned at or past it.

updateSettings 使用octokit自己生成的参数,这些字段拼写为 has_issues?: boolean 而不是说 has_issues?: boolean | undefined 这样下去 exactOptionalPropertyTypes (单位:千美元) Partial<T> 从您自己的设置中构建的图案完全没有指定它. repositoryPatch 是支持的出路, 它的存在,所以答案从来不是一个铸件:

import { repositoryPatch } from "@effected/github";

declare const config: { has_issues?: boolean | undefined; description?: string | undefined };

const patch = repositoryPatch({ has_issues: config.has_issues, description: config.description });
// a RepositoryPatch carrying only the fields that were actually set

放下钥匙就是电线需要的: PATCH 将一个缺失的字段读作"离开它",而一个明确 null 是一个值. RepositoryPatchDraft 是输入类型——相同的字段,每个字段都允许是明确的 undefined。将草稿构建为您可以使用的对象字面:按键循环会击败 TypeScript 两个索引访问器之间的关联,没有帮助者可以修复.

security_and_analysis 接受两个赤裸的 "enabled" 人类在配置文件中写到 { status: "enabled" } GitHub 自己的参数类型声明 。 触摸两个图形QL 设置的地图从不读取节点 id, 因此常见的大小写会保留一个请求 . ownerType 答题 "User" 或者说 "Organization" 用于存储器 Repo,这就是共享设置模板在将自己应用到个人存储器之前,只将GitHub接受的字段降入组织拥有的存储器.

GitHub 应用程序认证

GitHubApp.clientLayer 构建一个 GitHubClient 认证为应用程序安装 。 发行时会取消, 所以工作流程不会留下现场记录:

import { GitHubApp } from "@effected/github";
import { Redacted } from "effect";

// bind once — layers memoize by reference
const AppClient = GitHubApp.clientLayer({
  appId: "123456",
  privateKey: Redacted.make(process.env.GITHUB_APP_PRIVATE_KEY as string),
  owner: "effect-ts",
});
// Layer<GitHubClient, GitHubAppError> — provide it wherever a GitHubClient is needed

仅 GitHubApp 并且它的静电输入JWT的标志器——一个用平庸的符号认证的消费者从未到达它.

充当用户: OAuth 网络流量

GitHubUserAuth 运行 OAuth 网络流出一个 GitHub App(或 OAuth App) 作为用户: exchange 以重新定向的代码GitHub及其PKCE验证器交换用户的指使; refresh 延长到期补助金; revokeGrant 使用 HTTP Basic 客户端认证删除用户的全部授权。 它说话 fetch 直接,从不通过 GitHubClient,因此,一个在链接中只签名用户的工人既不是octokit,也不是JWT签名人:

import { GitHubUserAuth } from "@effected/github";
import { Effect, Redacted } from "effect";

// bind once — layers memoize by reference
const UserAuth = GitHubUserAuth.layer({
  clientId: "Iv23liExample",
  clientSecret: Redacted.make(process.env.GITHUB_CLIENT_SECRET as string),
});

const renew = (refreshToken: Redacted.Redacted<string>) =>
  Effect.gen(function* () {
    const auth = yield* GitHubUserAuth;
    return yield* auth.refresh({ refreshToken });
  }).pipe(
    // "reconnect": the user's grant is dead; "reconfigure": the app's secret or settings
    // are wrong, so keep the tokens and let it fail on to an operator
    Effect.catchTag("GitHubUserAuthFinal", (error) =>
      error.remedy === "reconnect" ? Effect.succeed("sign-in-again" as const) : Effect.fail(error),
    ),
  );

exchange 答题 GitHubUserTokens数字 : ExpiringUserTokens (访问令牌,刷新令牌, 和瞬间都过期,从 Clock)或(或) NonExpiringUserTokens 当应用程序不过期用户代号时; refresh 总是回答即将到期的一对, GitHub 在每个刷新时旋转刷新符号 。 两者都是可编码的,以道具为平板字符串,以时间为ISO即时.

每一个失败都是 GitHubUserAuthFinal (吉特胡布拒绝;其 code, (中文(简体) ), description 财务报告和审定财务报表 status 保留)或 GitHubUserAuthTemporary (网络,超时,5xx或429,或不是符号回复的机体——稍后重试并保留所持有的符号). 一个暂时的失败已经花费了刷新符号: GitHub 在每次刷新过程中旋转它, 所以刷新在到达 GitHub( a 2xx) 之后失败了 malformed,或一个 network 或者说 timeout 中继)的答案 bad_refresh_token 重新测试时,用户再次签名。 GitHub 拒绝使用 HTTP 200 和 an 的坏代码或刷新令牌 error 被理解为拒绝. 分会 remedy,从不单独在标签上: incorrect_client_credentials 也是最后的,一个处理器 将每个用户的符号都丢在任何 GitHubUserAuthFinal 在客户秘密被旋转时 给所有人签名 客户端的秘密,代码,验证人和信使在没有出错消息和没有保留原因的情况下出现. tokenUrl, (中文(简体) ), apiUrl, (中文(简体) ), apiVersion, (中文(简体) ), userAgent, (中文(简体) ), timeout (10秒钟)和 fetch 是选项,用于 GitHub 企业服务器、 工人和测试.

错误

GitHubError 覆盖REST, GitHubGraphQLError 覆盖图QL, GitHubAppError 覆盖应用程序认证, GitHubUserAuthFinal 编号 : GitHubUserAuthTemporary 覆盖 OAuth 用户流,以及 TokenPermissions 生产自己的 TokenPermissionError ——五种,不是每种资源之一:

import { GitHubError } from "@effected/github";
import { Effect } from "effect";

declare const upsertBranch: Effect.Effect<"created" | "reset", GitHubError>;

const program = upsertBranch.pipe(
  Effect.catchIf(GitHubError.hasKind("rateLimited"), (error) => Effect.logWarning(`retry after ${error.retryAfterMillis}ms`)),
);

GitHub的验证条目为 validation每个 GitHubValidationEntry 与 resource, (中文(简体) ), field, (中文(简体) ), code 财务报告和审定财务报表 message GitHub派来的 仅 already_exists 获得一个 kind (b) 其他有文件记载的编码(GitHubValidationCode),分支与 hasValidationCode 而不是阅读 reason数字 :

import { GitHubError } from "@effected/github";
import { Effect } from "effect";

declare const createRelease: Effect.Effect<void, GitHubError>;

const program = createRelease.pipe(
  Effect.catchIf(GitHubError.hasValidationCode("missing_field", "invalid"), (error) =>
    Effect.logError(`bad release parameters: ${error.validation?.map((entry) => entry.field).join(", ")}`),
  ),
);

重试处理一次, 在客户端中: RetryPolicy.default 重试a transport 或者说 rateLimited 失败的全速退后, 尊重 GitHub 的 retry-after 顶端为可配置的天花板. RetryPolicy.none 关闭它。 A 类 notFound, (中文(简体) ), rejected 或者说 unauthorized 失败从不重复——它不能改变在尝试之间的想法.

测试

每个资源船 makeTest(overrides?) 财务报告和审定财务报表 layerTest(overrides?):让成员进行测试练习,其他每个成员都会自行取名,所以测试证明它碰不到什么,它没有抽筋:

import { GitBranch } from "@effected/github";
import { Effect } from "effect";

const TestBranches = GitBranch.layerTest({
  upsert: () => Effect.succeed("created"),
});

GitHubClient.layerFixture(fixtures) 真实的双页:它构建一个 PageSource 在记录的阵列上,把它交给 活的客户端使用的同一页码引擎, 所以一个截取路径在测试和生产中 表现相同。 它的合约有三件事值得你先知道 然后再写信给它:

import { GitHubClient, GitHubError } from "@effected/github";

const fixtures = {
  request: {
    "GET /repos/{owner}/{repo}": { default_branch: "main" },
    // A recorded GitHubError *is* the response: this route fails with it.
    "PATCH /repos/{owner}/{repo}": GitHubError.notFound("updateSettings", "repo"),
  },
  paginate: { "GET /repos/{owner}/{repo}/rulesets": [{ id: 1, name: "main", source_type: "Repository" }] },
  requested: [], // filled in as the test runs
};

const TestClient = GitHubClient.layerFixture(fixtures);
// A route with no entry above DIES naming itself, rather than failing typed.
  • 一条没有被怀疑的路由默认死亡. 缺失的固定是测试接线而不是域结果,打入的失败只在代码中发出响亮而不能抓取——程序处理 GitHubError 每个资源都会将缺失的根变成不同的执行路径,然后由于命名为不固定的原因,断言失败. unstubbed: "fail" 键入未找到的路由失败,以及 "empty" 对于一个以决定而不是终点为主题的套房来说,这是一个空值.
  • 记录 GitHubError 值是响应. 套房就是用404分 422分 或限价的方式 在某条路由外倾只说"无线";一个有记录的错误说出哪条路由失败和原因.
  • fixtures.requested 记录每通电话. 每个 RecordedCall 携带 kind 用于表面的 route (文档名称为: graphql页:1 params 电话是用,而且 perPage 读一个标注。 params就是让测试证明什么方法 发送,这是任何正常写作都开启的问题.

特征

  • GitHubClient - 型号运输: request, (中文(简体) ), requestDecoded (用于生成地图以外的路径的强制-中程逃生舱口), paginate 编号 : paginateStream, (中文(简体) ), graphql,以及 rateLimit (只观察——这里没有代表你的油门).
  • Repo 编号 : RepoRef - 那个 { owner, repo } 协调,通过 R,与 Repo.provide 用于多存储程序.
  • GitHubRepository —— 寄存器作为 GitHub 自己生成的类型设置, + defaultBranch, (中文(简体) ), nodeId, (中文(简体) ), ownerType 表示只组织字段, applySettings 报告它实际发送的密钥,以及 topics 编号 : setTopics(names)时 setTopics 替换整个集并返回 GitHub 存储的内容(小写).
  • repositoryPatch 编号 : RepositoryPatchDraft 建立一个 updateSettings 从可能存在的字段补丁 undefined下页 exactOptionalPropertyTypes没有演员.
  • GitHubError 编号 : GitHubGraphQLError ——每次运输一次出错, kind- 开始与 hasKind 页:1 Effect.catchIfa REST 422的验证条目 validation,与 hasValidationCode。 。 。 .
  • RetryPolicy ——客户端的一项重试政策:全速回放,服务器推荐的延迟被按到上限.
  • GitHubApp - 应用JWT签名、安装代币薄荷/撤销、应用和安装身份,以及 clientLayer 用于认证 GitHubClient。 。 。 .
  • GitHubUserAuth – OAuth 用作用户的网络流量: PKCE 代码交换,刷新, 并批准取消 fright fetch,失败可分为最终(remedy: "reconnect" 或者说 "reconfigure")和临时的.
  • GitBranch 编号 : GitTag —— Git Database API refers, 与 upsert 将创建或重置的舞蹈倒向一个呼叫 GitTag.latestSemver 在一个通道中选择最新版本的标签.
  • CheckRun —— 说 withCheckRun 在每个出口路径上结束; CheckRunOutput.truncated() cut 输出到 GitHub 字节限制 .
  • PullRequest 编号 : PullRequestComment - 对两者都有好处, listFiles 用同样的满分回答 CommitFile 记录承诺读取返回, headSha编号 :baseSha 打开 PullRequestInfo附加时 CommentMarker 重新找到一个黏糊糊的评论. PullRequestInfo.mergeCommitSha 从图QL 读取 mergeCommit.oid 仅用于合并拉动请求,因为 REST 对象不再带有: get, (中文(简体) ), update 财务报告和审定财务报表 upsert 总是填满它,而 list 财务报告和审定财务报表 listAssociatedWithCommit 只填满 mergeCommits: true (每100个合并拉力请求一个GraphQL呼叫).
  • GitHubIssue 问题及其评论,包括: commentOnce 对于一个贴出一次且从未编辑过的标记性评论,以及 linkedIssues 为了什么拉拉要求关闭.
  • harvestIssueReferences 编号 : parseBareLineReference ——移动到两个收尾参考方言的相容性再导出 @effected/github-references,与 CLOSING_KEYWORDS 及其结果类型.
  • GitHubRelease - 发布和资产上传,包括一条路线(uploadAsset,带有端点的可选显示标签) GitHub 生成的端点地图外.
  • RepositorySecret 编号 : RepositoryVariable ——寄存器及环境机密和变量,被封存的盒加密了GitHub的秘密API的要求保存在一个模块中,没有其他导入的内容.
  • Ruleset 编号 : DeploymentEnvironment 编号 : RepositorySecurity 编号 : CodeScanning ——其余的配置等级:由名称和范围相匹配的规则,一元环境写作,三相安全切换 GitHub 保持了寄存器端点外,并用门口的语言检测设置了 CodeQL 默认设置.
  • WorkflowDispatch - 开火a workflow_dispatch 事件, list 与状态字符串 GitHub 报告,或发送和等待它创建的运行.
  • BotIdentity ——作者并犯"一瓶"罪,如: signoff 通过 Git Data API 实现的 DCO 拖车 git commit -s。 。 。 .
  • Attestation - 上传和列出针对主题摘要的证明;建立和签署捆绑是 @effected/sbom这是工作.
  • TokenPermissions ——纯粹的参照者,介于被授予的许可和需要的许可之间,只达到 effect。 。 。 .

许可证

麻省理工学院

版本与发布记录

@effected/github 共发布 45 个版本,首次发布于 2026/07/26;过去 12 个月发布了 45 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.32.1latest2026/11/112 天前
0.32.02026/11/102 天前
0.31.02026/11/103 天前
0.30.02026/11/094 天前
0.29.02026/11/067 天前
0.28.02026/11/0310 天前

关于 @effected/github 的常见问题

@effected/github 是什么?

在octokit核心请求表面上键入了 GitHub REST 和 GraphQL 服务, 并配备了应用认证和资源帮助器 .

如何安装 @effected/github?

在项目目录运行 npm install @effected/github,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:effect(~4.1.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@effected/github 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@effected/github 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@effected/github 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24.11.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@effected/github 可以商用吗?

@effected/github 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@effected/github 的下载量有多少?

根据 npm 官方下载统计,@effected/github 在 2026/10/13 – 2026/11/11 这 30 天内被下载 16,339 次,日均约 545 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@effected/github 还在维护吗?

最新版本 0.32.1 发布于 2026/11/11(2 天前);至今共发布 45 个版本,其中过去 12 个月发布了 45 个;首次发布于 2026/07/26。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。