@theholocron/holocron-plugin-fern 5.0.0-alpha.25 → 5.0.0-alpha.250

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/README.md CHANGED
@@ -42,7 +42,7 @@ pnpm add -D @theholocron/holocron-plugin-fern
42
42
  | `domain` | No | Base domain (`"wiki.theholocron.dev"`) or full path (`"wiki.theholocron.dev/myrepo"`). When a base domain is given, the repo name is appended automatically as a basepath. |
43
43
  | `fernOrg` | No | Fern workspace slug. Defaults to `config.org`. Set this when the Fern workspace name differs from the GitHub org (e.g. workspace `"holocron"`, org `"theholocron"`). |
44
44
 
45
- ## What `holocron setup` does
45
+ ## What `holocron repo setup` does
46
46
 
47
47
  1. **Writes `fern/fern.config.json`** — Fern workspace org name and pinned
48
48
  CLI version. Always overwritten.
@@ -79,7 +79,7 @@ DNS: add one CNAME record — `wiki.theholocron.dev` →
79
79
  Password protection is configured in the **Fern Dashboard**
80
80
  (`dashboard.buildwithfern.com`) — it is not configurable via `docs.yml` or
81
81
  any CLI flag. Configure access control manually in the dashboard after
82
- running `holocron setup`.
82
+ running `holocron repo setup`.
83
83
 
84
84
  ## CI secrets
85
85
 
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
- import { AuthError, ResolveTokenInput, Wiki, WikiDnsRecord, WikiProvisionOpts, WikiProxyConfig } from "@theholocron/cli";
2
- //#region src/capabilities/wiki.d.ts
3
- declare const FERN_VERSION = "5.114.1";
4
- interface FernWikiOptions {
1
+ import { AuthError, DnsRecordRequest, ResolveTokenInput, Wiki, WikiProvisionOpts, WikiProxyConfig } from "@theholocron/cli";
2
+ export declare const resolveToken: (input?: ResolveTokenInput) => string;
3
+ export declare const FERN_VERSION = "5.114.1";
4
+ interface FernWikiOptions extends ResolveTokenInput {
5
5
  /** Absolute path to the working repo root. Injected by the loader from RuntimeContext. */
6
6
  repoRoot?: string;
7
7
  /** Active org name (e.g. "theholocron"). Injected by the loader from RuntimeContext. */
@@ -36,36 +36,56 @@ interface FernWikiOptions {
36
36
  /**
37
37
  * One-line description shown on the global product switcher card.
38
38
  * Falls back to the top-level `description` field in `holocron.config.ts`
39
- * when omitted. Only used by `holocron sync --steps wiki`.
39
+ * when omitted. Only used by `holocron repo sync --steps wiki`.
40
40
  */
41
41
  subtitle?: string;
42
42
  /**
43
43
  * Font Awesome icon class for the product switcher card (e.g. `"fa-duotone fa-gear"`).
44
- * Only used by `holocron sync --steps wiki`.
44
+ * Only used by `holocron repo sync --steps wiki`.
45
45
  */
46
46
  icon?: string;
47
47
  }
48
- declare class FernWiki implements Wiki {
48
+ export declare class FernWiki implements Wiki {
49
49
  private readonly opts;
50
50
  readonly key: "wiki";
51
51
  readonly providerName = "fern";
52
52
  constructor(opts: FernWikiOptions);
53
53
  provision(callOpts?: WikiProvisionOpts): Promise<string>;
54
54
  proxyConfig(): WikiProxyConfig | null;
55
- dnsRecord(): WikiDnsRecord | null;
55
+ /**
56
+ * Confirms `HOLOCRON_FERN_TOKEN`/`FERN_TOKEN` resolves, or a Fern token
57
+ * is stored in the keyring — not a live check. Fern exposes no
58
+ * lightweight endpoint to verify a token actually works (the only
59
+ * token-consuming operation is a full `fern generate`, see
60
+ * holocron#1079); this only confirms one is configured, the same way
61
+ * CI's `fern generate --docs` step would find it.
62
+ *
63
+ * Deliberately ignores `cliToken` (`--token`): CI's step only ever sees
64
+ * the env var from a GitHub Actions secret, never a CLI flag — and a
65
+ * bare `--token <value>` meant for some OTHER provider is forwarded to
66
+ * every loaded plugin as a fallback (see AGENTS.md), so honoring it
67
+ * here would report "configured" even when no Fern-specific credential
68
+ * exists anywhere CI would actually look.
69
+ *
70
+ * Only `AuthError` (the specific "no token found" signal) is treated as
71
+ * `ok: false` — any other error (e.g. a real keyring failure) is a
72
+ * genuine problem and must surface as a failure, not get misreported as
73
+ * a missing token.
74
+ */
75
+ whoami(): Promise<{
76
+ ok: boolean;
77
+ }>;
78
+ dnsRecord(): DnsRecordRequest | null;
56
79
  }
57
- //#endregion
58
- //#region src/auth.d.ts
59
- declare const resolveToken: (input?: ResolveTokenInput) => string;
60
- //#endregion
61
- //#region src/index.d.ts
62
- type FernPluginOptions = FernWikiOptions;
63
- declare function wiki(opts: FernPluginOptions): Wiki;
64
- declare function createPlugin(options?: FernPluginOptions): {
80
+ export type FernPluginOptions = FernWikiOptions;
81
+ export declare function wiki(opts: FernPluginOptions): Wiki;
82
+ export declare function createPlugin(options?: FernPluginOptions): {
65
83
  name: string;
84
+ probes: {
85
+ connection: import("@theholocron/cli").Probe;
86
+ };
66
87
  capabilities: {
67
88
  wiki: () => Wiki;
68
89
  };
69
90
  };
70
- //#endregion
71
- export { AuthError, FERN_VERSION, FernPluginOptions, FernWiki, type FernWikiOptions, type ResolveTokenInput, createPlugin, resolveToken, wiki };
91
+ export { AuthError, type FernWikiOptions, type ResolveTokenInput };
package/dist/index.mjs CHANGED
@@ -1,7 +1,15 @@
1
+ import { AuthError, connectionProbe, createResolveToken } from "@theholocron/cli";
1
2
  import { mkdir, readFile, writeFile } from "node:fs/promises";
2
3
  import { join } from "node:path";
3
- import { AuthError, createResolveToken } from "@theholocron/cli";
4
- //#region src/capabilities/wiki.ts
4
+ import { stringifyJson } from "@theholocron/json-utils";
5
+ // src/auth.ts
6
+ const resolveToken = createResolveToken({
7
+ envName: "HOLOCRON_FERN_TOKEN",
8
+ vendorEnvName: "FERN_TOKEN",
9
+ keyringService: "fern",
10
+ errorMessage: "no Fern token found. Set HOLOCRON_FERN_TOKEN / FERN_TOKEN, or run: holocron auth set fern <token>"
11
+ });
12
+ // src/capabilities/wiki.ts
5
13
  const FERN_VERSION = "5.114.1";
6
14
  var FernWiki = class {
7
15
  opts;
@@ -33,6 +41,38 @@ var FernWiki = class {
33
41
  headers: { "X-Fern-Host": this.opts.domain.split("/")[0] }
34
42
  };
35
43
  }
44
+ /**
45
+ * Confirms `HOLOCRON_FERN_TOKEN`/`FERN_TOKEN` resolves, or a Fern token
46
+ * is stored in the keyring — not a live check. Fern exposes no
47
+ * lightweight endpoint to verify a token actually works (the only
48
+ * token-consuming operation is a full `fern generate`, see
49
+ * holocron#1079); this only confirms one is configured, the same way
50
+ * CI's `fern generate --docs` step would find it.
51
+ *
52
+ * Deliberately ignores `cliToken` (`--token`): CI's step only ever sees
53
+ * the env var from a GitHub Actions secret, never a CLI flag — and a
54
+ * bare `--token <value>` meant for some OTHER provider is forwarded to
55
+ * every loaded plugin as a fallback (see AGENTS.md), so honoring it
56
+ * here would report "configured" even when no Fern-specific credential
57
+ * exists anywhere CI would actually look.
58
+ *
59
+ * Only `AuthError` (the specific "no token found" signal) is treated as
60
+ * `ok: false` — any other error (e.g. a real keyring failure) is a
61
+ * genuine problem and must surface as a failure, not get misreported as
62
+ * a missing token.
63
+ */
64
+ async whoami() {
65
+ try {
66
+ resolveToken({
67
+ ...this.opts,
68
+ cliToken: void 0
69
+ });
70
+ return { ok: true };
71
+ } catch (err) {
72
+ if (err instanceof AuthError) return { ok: false };
73
+ throw err;
74
+ }
75
+ }
36
76
  dnsRecord() {
37
77
  const { org, domain, fernOrg } = this.opts;
38
78
  if (!domain) return null;
@@ -40,8 +80,11 @@ var FernWiki = class {
40
80
  const hostname = domain.split("/")[0];
41
81
  return {
42
82
  zone: hostname.split(".").slice(-2).join("."),
43
- cname: hostname,
44
- target: `${resolvedFernOrg}.docs.buildwithfern.com`
83
+ record: {
84
+ type: "CNAME",
85
+ name: hostname,
86
+ content: `${resolvedFernOrg}.docs.buildwithfern.com`
87
+ }
45
88
  };
46
89
  }
47
90
  };
@@ -49,10 +92,10 @@ async function writeFernConfig({ repoRoot, fernOrg }) {
49
92
  const fernDir = join(repoRoot, "fern");
50
93
  await mkdir(fernDir, { recursive: true });
51
94
  const org = fernOrg ?? "holocron";
52
- const content = JSON.stringify({
95
+ const content = stringifyJson({
53
96
  organization: org,
54
97
  version: FERN_VERSION
55
- }, null, 2) + "\n";
98
+ });
56
99
  await writeFile(join(fernDir, "fern.config.json"), content, "utf8");
57
100
  return `fern.config.json: org=${org}, version=${FERN_VERSION}`;
58
101
  }
@@ -127,24 +170,22 @@ function updateInstancesBlock(content, instanceUrl, customDomain, multiSource, r
127
170
  if (match[0] === newBlock) return content;
128
171
  return content.replace(blockRe, newBlock);
129
172
  }
130
- //#endregion
131
- //#region src/auth.ts
132
- const resolveToken = createResolveToken({
133
- envName: "HOLOCRON_FERN_TOKEN",
134
- vendorEnvName: "FERN_TOKEN",
135
- keyringService: "fern",
136
- errorMessage: "no Fern token found. Set HOLOCRON_FERN_TOKEN / FERN_TOKEN, or run: holocron auth set fern <token>"
137
- });
138
- //#endregion
139
- //#region src/index.ts
173
+ // src/index.ts
140
174
  function wiki(opts) {
141
175
  return new FernWiki(opts);
142
176
  }
143
177
  function createPlugin(options = {}) {
144
178
  return {
145
179
  name: "@theholocron/holocron-plugin-fern",
180
+ probes: { connection: connectionProbe({
181
+ provider: "Fern",
182
+ token: () => resolveToken(options),
183
+ verify: async () => ({
184
+ ok: true,
185
+ subject: "a token is set (Fern cannot check it from here)"
186
+ })
187
+ }) },
146
188
  capabilities: { wiki: () => wiki(options) }
147
189
  };
148
190
  }
149
- //#endregion
150
191
  export { AuthError, FERN_VERSION, FernWiki, createPlugin, resolveToken, wiki };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/holocron-plugin-fern",
3
- "version": "5.0.0-alpha.25",
3
+ "version": "5.0.0-alpha.250",
4
4
  "description": "Holocron plugin for Fern. Implements the wiki capability for engineering knowledge publishing.",
5
5
  "keywords": [
6
6
  "fern",
@@ -8,12 +8,12 @@
8
8
  "plugin",
9
9
  "wiki"
10
10
  ],
11
- "homepage": "https://github.com/theholocron/holocron/tree/main/packages/holocron-plugin-fern#readme",
11
+ "homepage": "https://github.com/theholocron/holocron/tree/main/plugins/holocron-plugin-fern#readme",
12
12
  "bugs": "https://github.com/theholocron/holocron/issues",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git+https://github.com/theholocron/holocron.git",
16
- "directory": "packages/holocron-plugin-fern"
16
+ "directory": "plugins/holocron-plugin-fern"
17
17
  },
18
18
  "license": "MIT",
19
19
  "author": "Newton Koumantzelis",
@@ -29,25 +29,28 @@
29
29
  "files": [
30
30
  "dist"
31
31
  ],
32
+ "dependencies": {
33
+ "@theholocron/json-utils": "^1.16.0"
34
+ },
32
35
  "devDependencies": {
33
- "@theholocron/eslint-config": "^8.0.0",
34
- "@theholocron/tsconfig": "^8.0.0",
35
- "@theholocron/tsdown-config": "^8.0.0",
36
- "@theholocron/vitest-config": "^8.0.0",
36
+ "@theholocron/eslint-config": "^8.8.2",
37
+ "@theholocron/tsconfig": "^8.8.2",
38
+ "@theholocron/tsdown-config": "^8.8.2",
39
+ "@theholocron/vitest-config": "^8.8.2",
37
40
  "@types/node": "^26",
38
- "@vitest/coverage-v8": "^4.1.11",
41
+ "@vitest/coverage-v8": "^5.0.5",
39
42
  "@vitest/eslint-plugin": "^1.6.27",
40
43
  "eslint": "^10.8.1",
41
44
  "eslint-plugin-n": "^18.3.0",
42
45
  "globals": "^17.11.0",
43
- "tsdown": "^0.22.14",
44
- "tsx": "4.23.12",
46
+ "tsdown": "^0.23.3",
47
+ "tsx": "4.23.15",
45
48
  "typescript": "^5.9.3",
46
- "vitest": "^4.1.11",
47
- "@theholocron/cli": "5.0.0-alpha.25"
49
+ "vitest": "^5.0.5",
50
+ "@theholocron/cli": "5.0.0-alpha.250"
48
51
  },
49
52
  "peerDependencies": {
50
- "@theholocron/cli": "5.0.0-alpha.25"
53
+ "@theholocron/cli": "5.0.0-alpha.250"
51
54
  },
52
55
  "engines": {
53
56
  "node": ">=22"