一键导入
octokit
Octokit.js (@octokit/rest) GitHub API 最佳實踐指南。當需要使用 GitHub REST/GraphQL API、設定 rate limiting、pagination、搜尋使用者、取得 contribution 資料時使用。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Octokit.js (@octokit/rest) GitHub API 最佳實踐指南。當需要使用 GitHub REST/GraphQL API、設定 rate limiting、pagination、搜尋使用者、取得 contribution 資料時使用。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | octokit |
| description | Octokit.js (@octokit/rest) GitHub API 最佳實踐指南。當需要使用 GitHub REST/GraphQL API、設定 rate limiting、pagination、搜尋使用者、取得 contribution 資料時使用。 |
| 套件 | 版本 |
|---|---|
@octokit/rest | 22.0.1 |
@octokit/core | 7.0.6 |
@octokit/plugin-throttling | 11.0.3 |
@octokit/plugin-retry | 8.1.0 |
所有 @octokit/* 套件使用 conditional exports:
{
"compilerOptions": {
"moduleResolution": "node16",
"module": "node16"
}
}
import { Octokit } from "@octokit/rest";
import { throttling } from "@octokit/plugin-throttling";
import { retry } from "@octokit/plugin-retry";
const MyOctokit = Octokit.plugin(throttling, retry);
const octokit = new MyOctokit({
auth: process.env.GITHUB_TOKEN,
userAgent: "gitstar/1.0.0",
throttle: {
onRateLimit: (retryAfter, options, octokit, retryCount) => {
octokit.log.warn(
`Rate limit for ${options.method} ${options.url} (retry ${retryCount + 1}, wait ${retryAfter}s)`
);
return retryCount < 2; // 重試兩次
},
onSecondaryRateLimit: (retryAfter, options, octokit) => {
octokit.log.error(`Secondary rate limit for ${options.method} ${options.url}`);
return false; // 不重試,需要調查原因
},
},
retry: { doNotRetry: [400, 401, 403, 404, 422] },
request: { retries: 3 },
});
Octokit.plugin() 回傳新 class(不修改原始):
const MyOctokit = Octokit.plugin(throttling, retry); // 新 constructor
const octokit = new MyOctokit({ /* options */ });
const allUsers = await octokit.paginate(octokit.rest.search.users, {
q: "location:Taiwan followers:>50",
sort: "followers",
order: "desc",
per_page: 100, // 永遠設 100,減少 API 呼叫
});
for await (const response of octokit.paginate.iterator(
octokit.rest.repos.listForOrg,
{ org: "octokit", per_page: 100 }
)) {
for (const repo of response.data) {
// 可以 break
}
}
const names = await octokit.paginate(
octokit.rest.repos.listForOrg,
{ org: "octokit", per_page: 100 },
(response) => response.data.map((repo) => repo.full_name)
);
const { data } = await octokit.rest.search.users({
q: "location:Taiwan followers:>100",
sort: "followers", // "followers" | "repositories" | "joined"
order: "desc",
per_page: 100,
});
location:Taiwan — 位置followers:>100 — 追蹤者數repos:>10 — repo 數language:TypeScript — 主要語言type:user 或 type:org| 端點 | 限制 |
|---|---|
| Search API | 30 req/min(authenticated) |
| Core API | 5,000 req/hr(authenticated) |
| Unauthenticated | 60 req/hr |
REST API 沒有 contribution 端點,必須用 GraphQL:
const query = `
query ($username: String!, $from: DateTime!, $to: DateTime!) {
user(login: $username) {
contributionsCollection(from: $from, to: $to) {
contributionCalendar {
totalContributions
}
restrictedContributionsCount
}
}
}
`;
const data = await octokit.graphql(query, {
username: "octocat",
from: "2025-01-01T00:00:00Z",
to: "2025-12-31T23:59:59Z",
});
import { RequestError } from "@octokit/request-error";
try {
await octokit.rest.repos.get({ owner, repo });
} catch (error) {
if (error instanceof RequestError) {
console.error(`Status: ${error.status}, Message: ${error.message}`);
if (error.status === 403) {
const retryAfter = error.response?.headers["retry-after"];
}
}
}
import type { Endpoints } from "@octokit/types";
// 端點回應型別
type SearchUsersResponse = Endpoints["GET /search/users"]["response"];
type UserData = Endpoints["GET /users/{username}"]["response"]["data"];
// 端點參數型別
type SearchUsersParams = Endpoints["GET /search/users"]["parameters"];
interface GitHubClient {
searchUsers(query: string, page: number): Promise<GitHubUser[]>;
}
// Production
class OctokitGitHubClient implements GitHubClient { /* ... */ }
// Test
class FakeGitHubClient implements GitHubClient {
async searchUsers() { return [{ login: "test" }]; }
}
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";
const server = setupServer(
http.get("https://api.github.com/search/users", ({ request }) => {
return HttpResponse.json({
total_count: 1,
incomplete_results: false,
items: [{ login: "testuser", id: 1, type: "User" }],
});
}),
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
Octokit.plugin(X) 回傳新 classZod v4 schema validation 最佳實踐指南。當需要定義 schema、驗證/解析 JSON 資料、type inference、或處理 unknown data 時使用。
Svelte 5 + Astro 整合最佳實踐指南。當需要建立 Svelte 元件、使用 runes API、整合 Astro islands、或用 Testing Library 測試 Svelte 元件時使用。
GitHub GraphQL API 最佳實踐指南。當需要使用 GraphQL 查詢使用者資料、處理 cursor pagination、計算 rate limit、或除錯 GraphQL errors 時使用。
gayanvoice/top-github-users 架構參考指南。當需要了解 GitHub 使用者排行榜的資料抓取管線、國家設定、排行計算邏輯、已知問題、或社群需求時使用。
Commander.js v14 CLI 框架最佳實踐。當需要建立 CLI 工具、解析命令列參數、設計 subcommands 時使用。
GitHub Actions CI/CD 最佳實踐指南。當需要設定 workflow、cron 排程、GitHub Pages 部署、使用 Octokit API、或處理 rate limiting 時使用。