@theholocron/holocron-plugin-fern 5.0.0-alpha.27 → 5.0.0-alpha.271

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,9 @@
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, PluginToken, ResolveTokenInput, Wiki, WikiProvisionOpts, WikiProxyConfig } from "@theholocron/cli";
2
+ export declare const resolveToken: import("@theholocron/cli").TokenResolver;
3
+ /** Every token this plugin takes, for `holocron doctor tokens`. */
4
+ export declare const tokens: PluginToken[];
5
+ export declare const FERN_VERSION = "5.114.1";
6
+ interface FernWikiOptions extends ResolveTokenInput {
5
7
  /** Absolute path to the working repo root. Injected by the loader from RuntimeContext. */
6
8
  repoRoot?: string;
7
9
  /** Active org name (e.g. "theholocron"). Injected by the loader from RuntimeContext. */
@@ -36,36 +38,56 @@ interface FernWikiOptions {
36
38
  /**
37
39
  * One-line description shown on the global product switcher card.
38
40
  * Falls back to the top-level `description` field in `holocron.config.ts`
39
- * when omitted. Only used by `holocron sync --steps wiki`.
41
+ * when omitted. Only used by `holocron repo sync --steps wiki`.
40
42
  */
41
43
  subtitle?: string;
42
44
  /**
43
45
  * Font Awesome icon class for the product switcher card (e.g. `"fa-duotone fa-gear"`).
44
- * Only used by `holocron sync --steps wiki`.
46
+ * Only used by `holocron repo sync --steps wiki`.
45
47
  */
46
48
  icon?: string;
47
49
  }
48
- declare class FernWiki implements Wiki {
50
+ export declare class FernWiki implements Wiki {
49
51
  private readonly opts;
50
52
  readonly key: "wiki";
51
53
  readonly providerName = "fern";
52
54
  constructor(opts: FernWikiOptions);
53
55
  provision(callOpts?: WikiProvisionOpts): Promise<string>;
54
56
  proxyConfig(): WikiProxyConfig | null;
55
- dnsRecord(): WikiDnsRecord | null;
57
+ /**
58
+ * Confirms `HOLOCRON_FERN_TOKEN`/`FERN_TOKEN` resolves, or a Fern token
59
+ * is stored in the keyring — not a live check. Fern exposes no
60
+ * lightweight endpoint to verify a token actually works (the only
61
+ * token-consuming operation is a full `fern generate`, see
62
+ * holocron#1079); this only confirms one is configured, the same way
63
+ * CI's `fern generate --docs` step would find it.
64
+ *
65
+ * Deliberately ignores `cliToken` (`--token`): CI's step only ever sees
66
+ * the env var from a GitHub Actions secret, never a CLI flag — and a
67
+ * bare `--token <value>` meant for some OTHER provider is forwarded to
68
+ * every loaded plugin as a fallback (see AGENTS.md), so honoring it
69
+ * here would report "configured" even when no Fern-specific credential
70
+ * exists anywhere CI would actually look.
71
+ *
72
+ * Only `AuthError` (the specific "no token found" signal) is treated as
73
+ * `ok: false` — any other error (e.g. a real keyring failure) is a
74
+ * genuine problem and must surface as a failure, not get misreported as
75
+ * a missing token.
76
+ */
77
+ whoami(): Promise<{
78
+ ok: boolean;
79
+ }>;
80
+ dnsRecord(): DnsRecordRequest | null;
56
81
  }
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): {
82
+ export type FernPluginOptions = FernWikiOptions;
83
+ export declare function wiki(opts: FernPluginOptions): Wiki;
84
+ export declare function createPlugin(options?: FernPluginOptions): {
65
85
  name: string;
86
+ probes: {
87
+ connection: import("@theholocron/cli").Probe;
88
+ };
66
89
  capabilities: {
67
90
  wiki: () => Wiki;
68
91
  };
69
92
  };
70
- //#endregion
71
- export { AuthError, FERN_VERSION, FernPluginOptions, FernWiki, type FernWikiOptions, type ResolveTokenInput, createPlugin, resolveToken, wiki };
93
+ export { AuthError, type FernWikiOptions, type ResolveTokenInput };
package/dist/index.mjs CHANGED
@@ -1,7 +1,17 @@
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
+ /** Every token this plugin takes, for `holocron doctor tokens`. */
13
+ const tokens = [resolveToken.token];
14
+ // src/capabilities/wiki.ts
5
15
  const FERN_VERSION = "5.114.1";
6
16
  var FernWiki = class {
7
17
  opts;
@@ -33,6 +43,38 @@ var FernWiki = class {
33
43
  headers: { "X-Fern-Host": this.opts.domain.split("/")[0] }
34
44
  };
35
45
  }
46
+ /**
47
+ * Confirms `HOLOCRON_FERN_TOKEN`/`FERN_TOKEN` resolves, or a Fern token
48
+ * is stored in the keyring — not a live check. Fern exposes no
49
+ * lightweight endpoint to verify a token actually works (the only
50
+ * token-consuming operation is a full `fern generate`, see
51
+ * holocron#1079); this only confirms one is configured, the same way
52
+ * CI's `fern generate --docs` step would find it.
53
+ *
54
+ * Deliberately ignores `cliToken` (`--token`): CI's step only ever sees
55
+ * the env var from a GitHub Actions secret, never a CLI flag — and a
56
+ * bare `--token <value>` meant for some OTHER provider is forwarded to
57
+ * every loaded plugin as a fallback (see AGENTS.md), so honoring it
58
+ * here would report "configured" even when no Fern-specific credential
59
+ * exists anywhere CI would actually look.
60
+ *
61
+ * Only `AuthError` (the specific "no token found" signal) is treated as
62
+ * `ok: false` — any other error (e.g. a real keyring failure) is a
63
+ * genuine problem and must surface as a failure, not get misreported as
64
+ * a missing token.
65
+ */
66
+ async whoami() {
67
+ try {
68
+ resolveToken({
69
+ ...this.opts,
70
+ cliToken: void 0
71
+ });
72
+ return { ok: true };
73
+ } catch (err) {
74
+ if (err instanceof AuthError) return { ok: false };
75
+ throw err;
76
+ }
77
+ }
36
78
  dnsRecord() {
37
79
  const { org, domain, fernOrg } = this.opts;
38
80
  if (!domain) return null;
@@ -40,8 +82,11 @@ var FernWiki = class {
40
82
  const hostname = domain.split("/")[0];
41
83
  return {
42
84
  zone: hostname.split(".").slice(-2).join("."),
43
- cname: hostname,
44
- target: `${resolvedFernOrg}.docs.buildwithfern.com`
85
+ record: {
86
+ type: "CNAME",
87
+ name: hostname,
88
+ content: `${resolvedFernOrg}.docs.buildwithfern.com`
89
+ }
45
90
  };
46
91
  }
47
92
  };
@@ -49,10 +94,10 @@ async function writeFernConfig({ repoRoot, fernOrg }) {
49
94
  const fernDir = join(repoRoot, "fern");
50
95
  await mkdir(fernDir, { recursive: true });
51
96
  const org = fernOrg ?? "holocron";
52
- const content = JSON.stringify({
97
+ const content = stringifyJson({
53
98
  organization: org,
54
99
  version: FERN_VERSION
55
- }, null, 2) + "\n";
100
+ });
56
101
  await writeFile(join(fernDir, "fern.config.json"), content, "utf8");
57
102
  return `fern.config.json: org=${org}, version=${FERN_VERSION}`;
58
103
  }
@@ -127,24 +172,22 @@ function updateInstancesBlock(content, instanceUrl, customDomain, multiSource, r
127
172
  if (match[0] === newBlock) return content;
128
173
  return content.replace(blockRe, newBlock);
129
174
  }
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
175
+ // src/index.ts
140
176
  function wiki(opts) {
141
177
  return new FernWiki(opts);
142
178
  }
143
179
  function createPlugin(options = {}) {
144
180
  return {
145
181
  name: "@theholocron/holocron-plugin-fern",
182
+ probes: { connection: connectionProbe({
183
+ provider: "Fern",
184
+ token: () => resolveToken(options),
185
+ verify: async () => ({
186
+ ok: true,
187
+ subject: "a token is set (Fern cannot check it from here)"
188
+ })
189
+ }) },
146
190
  capabilities: { wiki: () => wiki(options) }
147
191
  };
148
192
  }
149
- //#endregion
150
- export { AuthError, FERN_VERSION, FernWiki, createPlugin, resolveToken, wiki };
193
+ export { AuthError, FERN_VERSION, FernWiki, createPlugin, resolveToken, tokens, wiki };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/holocron-plugin-fern",
3
- "version": "5.0.0-alpha.27",
3
+ "version": "5.0.0-alpha.271",
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://docs.theholocron.dev/holocron/plugins/fern/",
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.1-alpha.1"
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",
37
36
  "@types/node": "^26",
38
- "@vitest/coverage-v8": "^4.1.11",
37
+ "@vitest/coverage-v8": "^5.0.5",
39
38
  "@vitest/eslint-plugin": "^1.6.27",
40
39
  "eslint": "^10.8.1",
41
40
  "eslint-plugin-n": "^18.3.0",
42
41
  "globals": "^17.11.0",
43
- "tsdown": "^0.22.14",
44
- "tsx": "4.23.12",
42
+ "tsdown": "^0.23.3",
43
+ "tsx": "4.23.15",
45
44
  "typescript": "^5.9.3",
46
- "vitest": "^4.1.11",
47
- "@theholocron/cli": "5.0.0-alpha.27"
45
+ "vitest": "^5.0.5",
46
+ "@theholocron/cli": "5.0.0-alpha.271",
47
+ "@theholocron/tsconfig": "^8.9.0-alpha.3",
48
+ "@theholocron/tsdown-config": "^8.9.0-alpha.3",
49
+ "@theholocron/eslint-config": "^8.9.0-alpha.3",
50
+ "@theholocron/vitest-config": "^8.9.0-alpha.3"
48
51
  },
49
52
  "peerDependencies": {
50
- "@theholocron/cli": "5.0.0-alpha.27"
53
+ "@theholocron/cli": "5.0.0-alpha.271"
51
54
  },
52
55
  "engines": {
53
56
  "node": ">=22"
@@ -57,9 +60,9 @@
57
60
  },
58
61
  "scripts": {
59
62
  "delivery.build": "tsdown",
60
- "sourceQuality.staticAnalysis": "holocron run sourceQuality.staticAnalysis --",
63
+ "sourceQuality.staticAnalysis": "eslint .",
61
64
  "test:watch": "vitest",
62
- "verification.typeSafety": "holocron run verification.typeSafety --",
63
- "verification.unitTests": "holocron run verification.unitTests --"
65
+ "verification.typeSafety": "tsc --noEmit",
66
+ "verification.unitTests": "vitest run"
64
67
  }
65
68
  }