@theholocron/holocron-plugin-github 2.0.0-alpha.19 → 2.0.0-alpha.21

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/dist/index.d.mts CHANGED
@@ -1,62 +1,14 @@
1
- import { Auth, Ci, CiRun, CiRunFilter, Environment, Environments, Issue, IssueSearchFilter, Issues, LifecycleResult, LifecycleSlot, RepoRef, RepoSettings, Ruleset, SecretScope, Secrets, Source, TrackerDoctorReport, TrackerUser } from "@theholocron/cli";
1
+ import { Auth, AuthError, Ci, CiRun, CiRunFilter, Environment, Environments, Issue, IssueSearchFilter, Issues, LifecycleResult, LifecycleSlot, RepoRef, RepoSettings, ResolveTokenInput, RestClient, RestClient as RestClient$1, Ruleset, SecretScope, Secrets, Source, TrackerDoctorReport, TrackerUser } from "@theholocron/cli";
2
2
 
3
3
  //#region src/auth.d.ts
4
- /**
5
- * Token resolution for the GitHub plugin. See README §Auth.
6
- *
7
- * Resolution order (matches the standard 4-step precedence set by
8
- * `.notes/tech-auth-bootstrap.spec.md`):
9
- * 1. explicit `token` argument (from `--token` flag)
10
- * 2. HOLOCRON_GH_TOKEN env var (preferred over GITHUB_TOKEN — clearer intent)
11
- * 3. GITHUB_TOKEN env var (auto-injected in GH Actions)
12
- * 4. keyring (com.theholocron.cli / "github")
13
- * 5. AuthError naming all four options + the bootstrap hint
14
- *
15
- * No `gh auth token` fallback by design — it usually has narrower
16
- * scopes than admin commands need.
17
- */
18
- declare class AuthError extends Error {
19
- name: string;
20
- }
21
- interface ResolveTokenInput {
22
- /** From `--token` CLI flag. */
23
- cliToken?: string;
24
- /** Env vars; passed in for testability. Defaults to `process.env`. */
25
- env?: NodeJS.ProcessEnv;
26
- /** Keyring lookup fn; passed in for testability. Defaults to `getToken(provider)`. */
27
- keyring?: (provider: string) => string | null;
28
- }
29
- declare function resolveToken(input?: ResolveTokenInput): string;
4
+ declare const resolveToken: (input?: import("@theholocron/http-client").ResolveTokenInput) => string;
30
5
  //#endregion
31
6
  //#region src/rest.d.ts
32
- /**
33
- * Thin REST wrapper around api.github.com.
34
- *
35
- * Adapted from rando-id/rando.id `packages/cli/src/adapters/gh-rest.ts`
36
- * `request<T>` method into a standalone class so each capability can
37
- * hold a reference and share the same auth/error handling.
38
- *
39
- * Errors throw `ProviderApiError` from `@theholocron/cli`, which the
40
- * orchestrator catches to soft-skip rather than abort the whole pipeline.
41
- */
42
- interface RestClientOptions {
7
+ declare function createGitHubRestClient(opts: {
43
8
  token: string;
44
- fetch?: typeof fetch;
45
9
  baseUrl?: string;
46
- }
47
- interface RequestOptions {
48
- method?: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
49
- body?: unknown;
50
- /** Skip JSON parse when true (204 No Content endpoints). */
51
- expectNoContent?: boolean;
52
- }
53
- declare class GitHubRestClient {
54
- private readonly token;
55
- private readonly fetchImpl;
56
- readonly baseUrl: string;
57
- constructor(opts: RestClientOptions);
58
- request<T>(path: string, opts?: RequestOptions): Promise<T>;
59
- }
10
+ fetch?: typeof fetch;
11
+ }): RestClient$1;
60
12
  //#endregion
61
13
  //#region src/sodium.d.ts
62
14
  /**
@@ -80,7 +32,7 @@ declare class GitHubSource implements Source {
80
32
  private readonly repoPath;
81
33
  private readonly repoRoot;
82
34
  private readonly workflowDir;
83
- constructor(rest: GitHubRestClient, opts: SourceOptions);
35
+ constructor(rest: RestClient, opts: SourceOptions);
84
36
  whoami(): Promise<{
85
37
  login: string;
86
38
  }>;
@@ -112,7 +64,7 @@ declare class GitHubSecrets implements Secrets {
112
64
  readonly key: "secrets";
113
65
  readonly providerName = "github";
114
66
  private readonly repoBase;
115
- constructor(rest: GitHubRestClient, opts: SecretsOptions);
67
+ constructor(rest: RestClient, opts: SecretsOptions);
116
68
  listSecrets(scope: SecretScope): Promise<string[]>;
117
69
  setSecret(scope: SecretScope, name: string, value: string): Promise<void>;
118
70
  deleteSecret(scope: SecretScope, name: string): Promise<void>;
@@ -129,7 +81,7 @@ declare class GitHubEnvironments implements Environments {
129
81
  readonly key: "environments";
130
82
  readonly providerName = "github";
131
83
  private readonly base;
132
- constructor(rest: GitHubRestClient, opts: EnvironmentsOptions);
84
+ constructor(rest: RestClient, opts: EnvironmentsOptions);
133
85
  listEnvironments(): Promise<Environment[]>;
134
86
  upsertEnvironment(env: Environment): Promise<void>;
135
87
  deleteEnvironment(name: string): Promise<void>;
@@ -145,7 +97,7 @@ declare class GitHubCi implements Ci {
145
97
  readonly key: "ci";
146
98
  readonly providerName = "github";
147
99
  private readonly base;
148
- constructor(rest: GitHubRestClient, opts: CiOptions);
100
+ constructor(rest: RestClient, opts: CiOptions);
149
101
  listRuns(filter?: CiRunFilter): Promise<CiRun[]>;
150
102
  getRun(id: string | number): Promise<CiRun>;
151
103
  /**
@@ -182,7 +134,7 @@ declare class GitHubIssues implements Issues {
182
134
  private readonly repoName;
183
135
  private readonly base;
184
136
  private readonly labels;
185
- constructor(rest: GitHubRestClient, opts: IssuesOptions);
137
+ constructor(rest: RestClient, opts: IssuesOptions);
186
138
  getMyself(): Promise<TrackerUser>;
187
139
  search(filter: IssueSearchFilter): Promise<Issue[]>;
188
140
  get(key: string): Promise<Issue>;
@@ -247,7 +199,7 @@ interface GitHubPluginOptions extends ResolveTokenInput {
247
199
  }
248
200
  interface PluginContext {
249
201
  options: GitHubPluginOptions;
250
- rest: GitHubRestClient;
202
+ rest: RestClient;
251
203
  repo: string;
252
204
  repoRoot: string;
253
205
  }
@@ -275,4 +227,4 @@ declare function createPlugin(options: GitHubPluginOptions): {
275
227
  */
276
228
  declare const AUTH_HINT: string;
277
229
  //#endregion
278
- export { AUTH_HINT, type Auth, AuthError, GitHubCi, GitHubEnvironments, GitHubIssues, GitHubPluginOptions, GitHubRestClient, GitHubSecrets, GitHubSource, PluginContext, ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, ci, createContext, createPlugin, encryptSecret, environments, issues, resolveToken, secrets, source, verifyToken };
230
+ export { AUTH_HINT, type Auth, AuthError, GitHubCi, GitHubEnvironments, GitHubIssues, GitHubPluginOptions, GitHubSecrets, GitHubSource, PluginContext, type ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, ci, createContext, createGitHubRestClient, createPlugin, encryptSecret, environments, issues, resolveToken, secrets, source, verifyToken };
package/dist/index.mjs CHANGED
@@ -1,32 +1,14 @@
1
1
  import { createRequire } from "node:module";
2
- import { ProviderApiError, getToken } from "@theholocron/cli";
2
+ import { AuthError, createResolveToken, createRestClient } from "@theholocron/cli";
3
3
  import { mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
4
4
  import { dirname, join } from "node:path";
5
5
  //#region src/auth.ts
6
- /**
7
- * Token resolution for the GitHub plugin. See README §Auth.
8
- *
9
- * Resolution order (matches the standard 4-step precedence set by
10
- * `.notes/tech-auth-bootstrap.spec.md`):
11
- * 1. explicit `token` argument (from `--token` flag)
12
- * 2. HOLOCRON_GH_TOKEN env var (preferred over GITHUB_TOKEN — clearer intent)
13
- * 3. GITHUB_TOKEN env var (auto-injected in GH Actions)
14
- * 4. keyring (com.theholocron.cli / "github")
15
- * 5. AuthError naming all four options + the bootstrap hint
16
- *
17
- * No `gh auth token` fallback by design — it usually has narrower
18
- * scopes than admin commands need.
19
- */
20
- var AuthError = class extends Error {
21
- name = "AuthError";
22
- };
23
- function resolveToken(input = {}) {
24
- const env = input.env ?? process.env;
25
- const keyring = input.keyring ?? getToken;
26
- const token = input.cliToken || env.HOLOCRON_GH_TOKEN || env.GITHUB_TOKEN || keyring("github");
27
- if (!token) throw new AuthError("no GitHub token found. Pass --token <PAT>, set HOLOCRON_GH_TOKEN / GITHUB_TOKEN, or run: holocron auth set github <PAT>");
28
- return token;
29
- }
6
+ const resolveToken = createResolveToken({
7
+ envName: "HOLOCRON_GH_TOKEN",
8
+ vendorEnvName: "GITHUB_TOKEN",
9
+ keyringService: "github",
10
+ errorMessage: "no GitHub token found. Pass --token <PAT>, set HOLOCRON_GH_TOKEN / GITHUB_TOKEN, or run: holocron auth set github <PAT>"
11
+ });
30
12
  //#endregion
31
13
  //#region src/repo.ts
32
14
  var RepoError = class extends Error {
@@ -619,53 +601,18 @@ async function ensureDir(path) {
619
601
  }
620
602
  //#endregion
621
603
  //#region src/rest.ts
622
- /**
623
- * Thin REST wrapper around api.github.com.
624
- *
625
- * Adapted from rando-id/rando.id `packages/cli/src/adapters/gh-rest.ts`
626
- * `request<T>` method into a standalone class so each capability can
627
- * hold a reference and share the same auth/error handling.
628
- *
629
- * Errors throw `ProviderApiError` from `@theholocron/cli`, which the
630
- * orchestrator catches to soft-skip rather than abort the whole pipeline.
631
- */
632
- var GitHubRestClient = class {
633
- token;
634
- fetchImpl;
635
- baseUrl;
636
- constructor(opts) {
637
- this.token = opts.token;
638
- this.fetchImpl = opts.fetch ?? globalThis.fetch;
639
- let url = opts.baseUrl ?? "https://api.github.com";
640
- while (url.endsWith("/")) url = url.slice(0, -1);
641
- this.baseUrl = url;
642
- }
643
- async request(path, opts = {}) {
644
- const url = `${this.baseUrl}${path}`;
645
- const headers = {
604
+ function createGitHubRestClient(opts) {
605
+ return createRestClient({
606
+ baseUrl: opts.baseUrl ?? "https://api.github.com",
607
+ token: opts.token,
608
+ extraHeaders: {
646
609
  accept: "application/vnd.github+json",
647
- authorization: `Bearer ${this.token}`,
648
610
  "x-github-api-version": "2022-11-28"
649
- };
650
- const init = {
651
- method: opts.method ?? "GET",
652
- headers
653
- };
654
- if (opts.body !== void 0) {
655
- headers["content-type"] = "application/json";
656
- init.body = JSON.stringify(opts.body);
657
- }
658
- const res = await this.fetchImpl(url, init);
659
- if (!res.ok) {
660
- const body = await res.text().catch(() => "");
661
- throw new ProviderApiError(`GitHub ${init.method} ${path} → ${res.status}`, res.status, body);
662
- }
663
- if (opts.expectNoContent || res.status === 204) return;
664
- const text = await res.text();
665
- if (!text) return void 0;
666
- return JSON.parse(text);
667
- }
668
- };
611
+ },
612
+ vendor: "GitHub",
613
+ fetch: opts.fetch
614
+ });
615
+ }
669
616
  //#endregion
670
617
  //#region src/verify-token.ts
671
618
  /**
@@ -679,10 +626,11 @@ var GitHubRestClient = class {
679
626
  * what we don't have yet at bootstrap time.
680
627
  */
681
628
  async function verifyToken(token, opts = {}) {
682
- const restOpts = { token };
683
- if (opts.baseUrl !== void 0) restOpts.baseUrl = opts.baseUrl;
684
- if (opts.fetch !== void 0) restOpts.fetch = opts.fetch;
685
- const rest = new GitHubRestClient(restOpts);
629
+ const rest = createGitHubRestClient({
630
+ token,
631
+ baseUrl: opts.baseUrl,
632
+ fetch: opts.fetch
633
+ });
686
634
  try {
687
635
  const me = await rest.request("/user");
688
636
  return {
@@ -701,7 +649,7 @@ async function verifyToken(token, opts = {}) {
701
649
  function createContext(options) {
702
650
  return {
703
651
  options,
704
- rest: new GitHubRestClient({
652
+ rest: createGitHubRestClient({
705
653
  token: resolveToken(options),
706
654
  baseUrl: options.baseUrl,
707
655
  fetch: options.fetch
@@ -751,4 +699,4 @@ function createPlugin(options) {
751
699
  */
752
700
  const AUTH_HINT = "generate a Personal Access Token at https://github.com/settings/tokens (scopes: repo, admin:repo_hook — plus admin:org for org-level ops), then run: holocron auth set github <PAT>";
753
701
  //#endregion
754
- export { AUTH_HINT, AuthError, GitHubCi, GitHubEnvironments, GitHubIssues, GitHubRestClient, GitHubSecrets, GitHubSource, ci, createContext, createPlugin, encryptSecret, environments, issues, resolveToken, secrets, source, verifyToken };
702
+ export { AUTH_HINT, AuthError, GitHubCi, GitHubEnvironments, GitHubIssues, GitHubSecrets, GitHubSource, ci, createContext, createGitHubRestClient, createPlugin, encryptSecret, environments, issues, resolveToken, secrets, source, verifyToken };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/holocron-plugin-github",
3
- "version": "2.0.0-alpha.19",
3
+ "version": "2.0.0-alpha.21",
4
4
  "description": "Holocron plugin for GitHub. Implements source, ci, secrets, environments, and issues capabilities against the GitHub REST API.",
5
5
  "homepage": "https://github.com/theholocron/holocron/tree/main/packages/holocron-plugin-github#readme",
6
6
  "bugs": "https://github.com/theholocron/holocron/issues",
@@ -21,17 +21,18 @@
21
21
  }
22
22
  },
23
23
  "peerDependencies": {
24
- "@theholocron/cli": "2.0.0-alpha.19"
24
+ "@theholocron/cli": "2.0.0-alpha.21"
25
25
  },
26
26
  "dependencies": {
27
27
  "libsodium-wrappers": "^0.7.15"
28
28
  },
29
29
  "devDependencies": {
30
- "@theholocron/eslint-config": "^5.1.1",
31
- "@theholocron/tsconfig": "^4.1.0",
32
- "@tsconfig/node-lts": "^24.0.0",
30
+ "@types/node": "^26",
31
+ "@theholocron/eslint-config": "^5.2.0",
32
+ "@theholocron/tsconfig": "^6.0.0",
33
+ "@theholocron/tsdown-config": "^5.1.2",
34
+ "@theholocron/vitest-config": "^5.2.0",
33
35
  "@types/libsodium-wrappers": "^0.7.14",
34
- "@vitest/coverage-v8": "^3.2.6",
35
36
  "@vitest/eslint-plugin": "^1.6.23",
36
37
  "eslint": "^10.7.0",
37
38
  "eslint-plugin-n": "^18.2.2",
@@ -39,8 +40,8 @@
39
40
  "tsdown": "^0.22.3",
40
41
  "tsx": "^4.22.4",
41
42
  "typescript": "^5.9.3",
42
- "vitest": "^3.2.6",
43
- "@theholocron/cli": "2.0.0-alpha.19"
43
+ "vitest": "^4.1.10",
44
+ "@theholocron/cli": "2.0.0-alpha.21"
44
45
  },
45
46
  "publishConfig": {
46
47
  "access": "public"